15

クラス間で同期ブロックを使用する方法を知りたいです。つまり、複数のクラスでブロックを同期したいのですが、それらはすべて同じオブジェクトで同期しています。これを行う方法を考えた唯一の方法は次のとおりです。

//class 1
public static Object obj = new Object();

someMethod(){
     synchronized(obj){
         //code
     }
}


//class 2
someMethod(){
     synchronized(firstClass.obj){
         //code
     }
}

この例では、最初のクラスで同期する任意のオブジェクトを作成し、2 番目のクラスでもそれを静的に参照して同期しました。ただし、これは私には悪いコーディングのようです。これを達成するためのより良い方法はありますか?

4

7 に答える 7

3

見た目が良くなくても、あなたのコードは有効に思えます。ただし、同期しているオブジェクトを最終的に作成してください。ただし、実際のコンテキストによっては、いくつかの考慮事項がある場合があります。

いずれにせよ、アーカイブしたいものを Javadocs に明確に記載する必要があります。

別のアプローチは、FirstClassたとえば同期することです

synchronized (FirstClass.class) {
// do what you have to do
} 

ただし、すべてのsynchronizedメソッドFirstClassは上記の同期ブロックと同じです。つまり、それらもsynchronized同じオブジェクト上にあります。- 文脈によっては、より良いかもしれません。

BlockingQueue他の状況下では、db アクセスなどで同期する必要がある場合に、何らかの実装を希望する場合があります。

于 2014-07-16T02:25:27.487 に答える
2

同期ブロックをまったく使用して、間違った方向に進んでいると思います。Java 1.5 以降java.util.concurrent、同期の問題を高レベルで制御できるパッケージがあります。

たとえば、Semaphore単純な同期のみが必要な基本的な作業を提供するクラスがあります。

Semaphore s = new Semaphore(1);
s.acquire();
try {
   // critical section
} finally {
   s.release();
}

この単純なクラスでさえ、同期以上のものを提供します。たとえば、tryAcquire()ロックが取得されたかどうかに関係なくすぐに戻り、ロックが使用可能になるまで重要ではない作業を実行するオプションが残される可能性があります。

これらのクラスを使用すると、オブジェクトの目的が明確になります。一般的なモニター オブジェクトは誤解される可能性がありますSemaphoreが、デフォルトでは、a はスレッドに関連付けられたものです。

同時実行パッケージをさらに詳しく調べるとReentrantReadWriteLock、書き込み操作のみが実際に他の読み取り/書き込みに対して同期される一方で、多くの同時読み取り操作が存在する可能性があることを定義できるような、より具体的な同期クラスが見つかります。Phaser特定のタスクが同期的に実行されるようにスレッドを同期できる ( の反対のようなものsynchornized) と、特定の状況で同期をまったく不要にする可能性のある多くのデータ構造を見つけることができます。

synchronized総じて:理由が正確にわかっていないか、Java 1.4 にこだわっていない限り、plain を使用しないでください。読んで理解するのは難しく、おそらく、Semaphoreまたはの上位関数の少なくとも一部を実装しているでしょうLock

于 2017-09-28T09:11:22.287 に答える