Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

java - Regarding countdown latch implementation

I have been going through the program which starts three threads and print their corresponding value such that T3 is executed first, then the T1 thread, and lastly the T2 thread is executed. Below is the program.

I just want to know if you guys could help in converting this program with respect to countdown latch, as I want to develop it using this mechanism or it can be also done through counting semaphore.

From the answer to this related question:

    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();
  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

We consider each pair of threads Tw, Ts such as Tw is waiting on Ts to commence its work. In your setup, there are 2 such pairs:

T1, T3
T2, T1

For each pair, we will create one CountDownLatch, and provide it to each thread of the pair. Then Tw will call await on the latch before starting its work, and Ts will call countDown at the end of its own work.

Since T1 belongs to both pairs, it will receive both latches. However, in the first case, T1 is a waiting thread, and in the second, T1 is a signaling thread, therefore its code will have to be amended accordingly.

Of course you will have to remove the join calls and related infrastructure.

Since your question title asks about latch implementation, let's just briefly say that the same semantics can be produced using a Semaphore initialized at 0, and where countDown would actually be a release of the semaphore, while await would be an acquire of that semaphore.

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();
  }
}

The proposed sample implementation uses auxiliary runnables to take care of the latching process, thus allowing us to compose each task using these runnables, instead of deriving the Printer class for each specific case (we save at least one class).

The Semaphore based similar implementation is left as an exercise for the reader.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...