16

Java で並行処理とスレッドの学習を開始しました。私は同期の基本 (つまり、それが何をするか) を知っています。概念的には、Java で複数のスレッドを持つ共有リソースへの相互排他的アクセスを提供することを理解しています。しかし、以下のような例に直面したとき、それを同期させるのが良い考えかどうかについて私は混乱しています. コードのクリティカル セクションを同期する必要があり、このキーワードを過度に使用しないでください。そうしないと、パフォーマンスに影響します。

public static synchronized List<AClass> sortA(AClass[] aArray) 
{
    List<AClass> aObj = getList(aArray);

    Collections.sort(aObj, new AComparator());

    return aObj;
}

public static synchronized List<AClass> getList(AClass[] anArray) 
{
    //It converts an array to a list and returns
}
4

6 に答える 6

13

各スレッドが異なる配列を渡すと仮定すると、残りの変数はローカルであるため、同期は必要ありません。

sortA代わりに、同じ配列への参照をすべて呼び出して渡すいくつかのスレッドを起動すると、相互に干渉するため、 がないと問題が発生します。synchronized

スレッドが同じ配列を渡したとしても、異なるオブジェクトを取得するように、getListメソッドが配列から new を返すように例から見えることに注意してください。これは誤解を招きます。たとえば、 usingは指定された配列に裏打ちされた を作成しますが、javadoc には明確に記載されているため、これには注意してください。ListListArrays.asListListChanges to the returned list "write through" to the array.

于 2012-05-14T10:17:57.460 に答える
5

通常、複数の呼び出し間でデータを共有していて、データが変更されて不整合が生じる可能性がある場合、同期が必要になります。データが読み取り専用の場合、同期する必要はありません。

上記のコード スニペットでは、共有されているデータはありません。メソッドは提供された入力に対して機能し、出力を返します。複数のスレッドがメソッドの 1 つを呼び出す場合、各呼び出しには独自の入力と出力があります。したがって、どこにも矛盾が生じる可能性はありません。したがって、上記のスニペットのメソッドは同期する必要はありません。

同期を不必要に使用すると、関連するオーバーヘッドのためにパフォーマンスが確実に低下するため、必要な場合にのみ慎重に使用する必要があります。

于 2012-05-14T10:23:32.227 に答える
2

正しく計算した同期は、アプリケーションのスループットに影響を与え、スレッドの枯渇につながる可能性もあります。

同時実行パッケージの下のコレクションが実装されているため、すべての get は基本的に非ブロックである必要があります。

あなたの例のように、すべての呼び出しスレッドは配列の独自のコピーを渡します。getList同期する必要はありませんsortA。他のすべての変数はローカルであるため、メソッドです。

ローカル変数はスタック上に存在し、すべてのスレッドが独自のスタックを持っているため、他のスレッドが干渉することはできません。

オブジェクトの状態を変更するときは、他のスレッドが一貫した状態で参照する必要があります。呼び出しによってオブジェクトの状態が変更されない場合、同期は必要ありません。

于 2012-05-14T10:19:48.320 に答える
2

静的メソッドは共有状態に依存しないため、同期する必要はありません。

于 2012-05-14T10:17:15.680 に答える
2

synchronizedシングルスレッドコードでは使用しません。つまり、オブジェクトが複数のスレッドによってアクセスされる可能性がない場合です。

これは明白に見えるかもしれませんが、JDK で使用される StringBuffer の ~99% は 1 つのスレッドでしか使用できません (同期されていない) StringBuilder に置き換えることができます

于 2012-05-14T10:35:59.043 に答える
2

いつ同期を使用するか、そうでないかなどのルールは定義されていません。コードが同時スレッドによってアクセスされないことが確実な場合は、同期の使用を避けることができます。

于 2012-05-14T10:17:57.560 に答える