-2

我一直在经历启动三个线程并打印它们相应的值的程序,这样首先T3执行,然后是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, TsTw等待Ts开始其工作。在您的设置中,有 2 个这样的对:

T1, T3
T2, T1

对于每一对,我们将创建一个CountDownLatch,并将其提供给该对的每个线程。然后Twawait在开始工作之前调用闩锁,并在自己的工作结束时Ts调用。countDown

由于T1属于两对,它将接收两个锁存器。但是,第一种情况T1是等待线程,第二种T1情况是信号线程,因此必须对它的代码进行相应的修改。

当然,您将不得不删除join调用和相关的基础设施。

由于您的问题标题询问了闩锁的实现,所以我们简单地说,可以使用Semaphore初始化的 at产生相同的语义0,并且 wherecountDown实际上是release信号量的 a ,而await将是acquire那个信号量的 an 。

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为每个特定情况派生类(我们至少保存一个类)。

基于Semaphore类似的实现留给读者练习。

于 2013-02-22T19:36:30.920 回答