調整された方法のシナリオで CyclicBarrier と共に join() を使用する方法について詳しく学ぼうとしました - 送信と受信。基本的なコードは以前のポスターのもので、特定のループ アカウント (例: 10 回) を実行するように変更しました。コードは次のとおりです。
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
public class Test {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2);
Receiver receiver = new Receiver(barrier);
Sender sender = new Sender(barrier);
Thread r = new Thread(receiver);
Thread s = new Thread(sender);
r.start();
s.start();
try {
r.join();
s.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("It is over....");
}
}
class Sender implements Runnable {
private CyclicBarrier barrier;
static boolean stop = false;
private static int i = 1;
public static int limit = 10 ;
public Sender(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while ( !stop ) {
try {
// Wait for notify.
Thread.sleep(1);
// Now do SEND.
int j = getI();
System.out.println(j);
System.out.println("SEND -" + j );
barrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static int getI() {
return i;
}
public static void setI(int i) {
Sender.i = i;
}
}
class Receiver implements Runnable {
private CyclicBarrier barrier;
public Receiver(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while ( Sender.getI() <= Sender.limit ) {
// Then notify.
try {
barrier.await();
int k = Sender.getI();
// Wait for ACK (the sleep just simulates that).
System.out.println("ACK -" + k );
Sender.setI(++k);
if ( Sender.getI() > Sender.limit ) {
System.out.println(k);
Sender.stop = true;
// barrier.reset();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
ただし、解決できなかった結果に遭遇し、await() のロジックとほとんど混乱していません。結果は予想通りのようですが、SENDとACKが交互に10回。実際には SEND で余分な時間を実行し、10 回目の -ACK 実行でステータス Sender.stop を true 状態に変更しても、Send-run() の while ループが「停止」しなかったようです。また、スレッドは10回(または11回)後に終了しなかったため、main()で「終了しました..」出力に入ることがありませんでした。プロセスがどこかでハングしているように見えました。