1

m1、、、などの一連のメソッドがm2ありm3ますm4。それぞれが前のメソッドが終了するのを待つ必要があります。を呼び出す場合はm3、待機する必要がありm2ます。終了したら、メソッドごとにフラグを使用することを考えました。しかし、通知するために、とm1言う場合notify()、私はこの通知m2を他の待機中のメソッドではなく、に対してのみ通知したいと思います。

入力メソッドと出力メソッドとして、をA持つコンポーネントがあります。発生すると、出力を生成するために呼び出します。ただし、、は順番に実行する必要があり、さまざまなクラスから呼び出すことができます。待機中の対応する信号がそこにある必要があります。m1m2m3m4m3m4m1m2m3

どうすればこれを実装できますか?

4

5 に答える 5

2

BlockingQueues は役に立ちますが、ThreadPoolExecutor を使用している場合は役に立ちません。ThreadPoolExecutor には、キューがいっぱいになったときにブロックするすぐに使用できるソリューションは付属していません (これはエグゼキューターの一部であり、キューの機能ではありません。エグゼキューターは決してブロックしない BlockingQueue.offer を使用し、キューがfull は RejectedExecutionHandler を使用します)。キューに何かを入れることができるまでブロックする独自の RejectedExecutionHandler を実装できますが、ロックを使用した簡単な決定論的な方法を次に示します。

ReentrantLock l1 = new ReentrantLock();
ReentrantLock l2 = new ReentrantLock();
ReentrantLock l3 = new ReentrantLock();

l1.lock();
l2.lock();
l3.lock();


// pass l1,l2,l3 along to the threads running these methods, so they are available to the methods:

public void m1() {
 try {
  // do stuff
 }
 finally {
   l1.unlock();
 }
}

public void m2() {
 l1.lock();
 try {
  // do stuff
 }
 finally {
   l2.unlock();
 }
}

public void m3() {
 l2.lock();
 try {
  // do stuff
 }
 finally {
   l3.unlock();
 }
}

public void m4() {
 l3.lock();
 // do stuff
}
于 2012-06-01T12:57:47.697 に答える
1

ロックは必要ありませんが、バリア:m(n + 1)は、m(n)が呼び出されるまで待機する必要があります。以下のコードは、シーケンスまたはメソッドの呼び出しが1つしかないことを前提としています(m1 / 2/3は、異なるスレッドから、または同じスレッドで適切なシーケンスで呼び出されます。そうしないと、ラッチで永久に待機します)。それが複数回発生する可能性がある場合は、リセットする必要があります(または、フェイザーを使いこなすことができます)。

private CountDownLatch m2latch = new CountDownLatch(1);
private CountDownLatch m3latch = new CountDownLatch(1);

public void m1() {
  // handle input
  m2latch.countDown();
}

public void m2() {
  m2latch.await();
  // handle input (m1 has been called)
  m3latch.countDown();
}

public void m3() {
  m3latch.await();
  // do output (both m1 + m2 have been called)
}

ただし、これは少し奇妙な設計です。順番に実行したいので、すべての入力が入力されるまで待機するoutputメソッドですべての作業を実行する必要があります。

 private CountDownLatch inputLatch = new CountDownLatch(3);
 private Object[] input = new Object[3];

 public void setInput(int i, Object data) {
   input[i] = data;
   inputLatch.countDown(); // perhaps better check all input set
 }

 public Object processInput() {
   inputLatch.await();
   return process(input); // process in sequence
 }
于 2012-06-01T14:39:15.817 に答える
0

カウンターを int として設定し、各メソッドは、カウンターがその数値に達するまで待機してから実行する必要があります。そうすれば、各メソッドはカウンターをインクリメントするだけで済み、後でさらに挿入できます。

于 2012-06-01T12:54:27.347 に答える
0

簡単な解決策は、4 つの異なるロック オブジェクトを使用することです。(または実際には同じスレッドで実行しますが、それはおそらくあなたが望むものではありません。)

もう少し詳しく説明すると、より洗練された解決策があるかもしれません。

于 2012-06-01T12:56:13.297 に答える
0

私の提案は、問題を正しく理解したかどうかによって異なります。

public void m4() {
    m3();
    do something;
}

public void m3() {
    m2();
    do something;
}

public void m2() {
   m1();
   do something;
}

public void m1() {
   do something;
}
于 2012-06-01T13:04:00.020 に答える