9

だから私はこれに似たコードを持っています

synchronized(objectOne){ do stuff }
synchronized(objectTwo){ do stuff }

objectOneこれに関する問題は、 のロックが利用可能であっても、プログラムが のロックを待機することobjectTwoです。私がやろうとしているのは、 と の両方をロックしてみてobjectOneobjectTwoどちらのロックを最初に取得しても、そのロックの処理を行うということです。私は解決策を思いつきましたが、それはかなりハッキーだと思います.誰かがより良いアイデアを持っているかどうか疑問に思っています.

ここに私の考えがあります: 2 つのスレッドを開始し、それぞれがロックを待機してから、メイン スレッドがCountDownLatchを待機します。したがって、次のような結果になります。

CountDownLatch latch = new CountDownLatch(2);

new Thread(new Runnable(){
public void run(){
    synchronized(objectOne) { do stuff }
    latch.countDown();
}).start();

new Thread(new Runnable(){
public void run(){
    synchronized(objectTwo) { do stuff }
    latch.countDown();
}).start();

latch.await();
4

4 に答える 4

5

Lockメソッドを提供するものを使用する必要があると思いますboolean tryLock()

戻り値: ロックが取得された場合は true、それ以外の場合は false

少なくとも 1 つのロックがある場合は、作業を続行します。

于 2012-11-15T02:02:07.623 に答える
2

ジョブの 2 つのキューが必要な場合があり、2 つのスレッドがそれぞれキューをポーリングしてジョブを実行します。

objectOne に関連するジョブの場合は、キュー #1​​ に入れます。キュー#2 の objectTwo に関連するジョブ。

worker1.queue.put( new Runnable(){ public void run() { do stuff } } );
worker2.queue.put( new Runnable(){ public void run() { do stuff } } );

----

class Worker extends Thread

    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

    public void run()
        while(true)
            queue.take().run();
于 2012-11-15T02:14:06.973 に答える
0

量によっては、stuff複数のスレッドをスピンオフして処理を行うためのオーバーヘッドが増える可能性があります。stuff十分に高速な操作である場合は、単一のスレッドで処理を実行するのが最適な場合があります。あなたはそれを知るために時間を計らなければならないでしょう。

于 2012-11-15T02:47:31.347 に答える
0

少なくともそれが1回限りの状況であれば、私はあなたのハックが好きです. それは言った...

この種のことを頻繁に行っていて、「ハックの少ない」ものが必要な場合は、ExecutorService#invokeAll()をお勧めします。これは Callable のリストを取得し、それらをスレッド プールで実行し、すべて完了するまでブロックします。

スケッチ:

ExecutorService es = Executors.newCachedThreadPool(); // for example...
List<Future<Void>> results = es.invokeAll(new ArrayList {{ 
        add(new Callable<Void> { 
            public Void call() { synchronized(objectOne) { do stuff } }
        });
        add(new Callable<Void> { 
            public Void call() { synchronized(objectTwo) { do stuff } }
        });
    }});
// both Callables are done when you get here

これは明らかに、アプリのこの時点でこれらのメソッドを異なるスレッドから呼び出しても問題ないことを前提としています。何らかの理由で同じスレッドから両方を呼び出す必要がある場合はtryLock、Bhesh Gurung の回答で説明されているように、使用してビジー待機する運命にあると思います。

于 2012-11-15T05:09:48.800 に答える