2

調整された方法のシナリオで 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()で「終了しました..」出力に入ることがありませんでした。プロセスがどこかでハングしているように見えました。

4

0 に答える 0