-2

T3私は、3つのスレッドを開始し、最初に実行され、次にT1スレッド、最後にスレッドが実行されるように、対応する値を出力するプログラムを実行してきT2ました。以下はプログラムです。

このメカニズムを使用して開発したいので、カウントダウンラッチに関してこのプログラムを変換するのに役立つかどうかを知りたいだけです。または、セマフォをカウントすることによっても実行できます。

この関連する質問への回答から:

    public class Test {
  static class Printer implements Runnable {
    private final int from;
    private final int to;
    private Thread joinThread;

    Printer(int from, int to, Thread joinThread) {
      this.from = from;
      this.to = to;
      this.joinThread = joinThread;
    }

    @Override
    public void run() {
      if(joinThread != null) {
        try {
          joinThread.join();
        } catch (InterruptedException e) { /* ignore for test purposes */ }
      }
      for (int i = from; i <= to; i++) {
        System.out.println(i);
      }
    }
  }
  public static void main(String[] args) throws InterruptedException {

    Thread T3 = new Thread(new Printer(10, 15, null));
    Thread T1 = new Thread(new Printer(1, 5, T3));
    Thread T2 = new Thread(new Printer(6, 10, T1));
    T1.start();
    T2.start();
    T3.start();
  }
}
4

1 に答える 1

1

が作業を開始するのを待っているTw, Tsなどのスレッドの各ペアを検討します。セットアップには、そのようなペアが 2 つあります。TwTs

T1, T3
T2, T1

ペアごとに を 1 つ作成しCountDownLatch、ペアの各スレッドに提供します。次に、作業を開始する前にラッチをTw呼び出し、自身の作業の最後に呼び出します。awaitTscountDown

T1両方のペアに属しているため、両方のラッチを受け取ります。ただし、最初のケースでT1は待機中のスレッドであり、2 番目のケースではT1シグナル スレッドであるため、それに応じてコードを修正する必要があります。

もちろん、join通話と関連するインフラストラクチャを削除する必要があります。

Semaphoreあなたの質問のタイトルはラッチの実装について尋ねているので、初期化された at0を使用して同じセマンティクスを生成できることを簡単に言いましょcountDownう。releaseawaitacquire

public class Test {
  private CountdownLatch latch;
  private Runnable runnable;
  class Tw implements Runnable {
     Tw(CountdownLatch l, Runnable r) {
        latch = l;
        runnable = r;
     }
     @override
     public void run(){
       latch.await();
       runnable.run();
     }
  }

  class Ts implements Runnable {
     CountdownLatch latch;
     Runnable runnable;
     Ts(CountdownLatch l, Runnable r){
        latch = l;
        runnable = r;
     }
     @override
     public void run(){
       runnable.run();
       latch.countDown();
     }
  }

  static class Printer implements Runnable {
    private final int from;
    private final int to;

    Printer(int from, int to) {
        this.from = from;
        this.to = to;
    }

    @Override
    public void run() {
        for (int i = from; i <= to; i++) {
            System.out.println(i);
        }
    }

  public static void main(String[] args) throws InterruptedException {
    CountdownLatch l31 = new CountdownLatch(1), l12 = new CountdownLatch(1);    
    Thread T3 = new Thread(new Ts(l31, new Printer(10, 15, null)));
    Thread T1 = new Thread(new Tw(l31, new Ts(l12, new Printer(1, 5, T3))));
    Thread T2 = new Thread(new Tw(l12, new Printer(6, 10, T1)));
    T1.start();
    T2.start();
    T3.start();
  }
}

提案されたサンプル実装では、補助ランナブルを使用してラッチ プロセスを処理するPrinterため、特定のケースごとにクラスを派生させる代わりに、これらのランナブルを使用して各タスクを構成できます (少なくとも 1 つのクラスを保存します)。

ベースのSemaphore同様の実装は、読者の演習として残されています。

于 2013-02-22T19:36:30.920 に答える