【问题标题】:Regarding countdown latch implementation关于倒计时锁存器的实现
【发布时间】:2013-02-08 11:05:29
【问题描述】:

我一直在执行启动三个线程并打印它们对应的值的程序,这样首先执行T3,然后执行T1线程,最后执行T2线程。下面是程序。

我只是想知道你们是否可以帮助转换这个关于倒计时锁存器的程序,因为我想使用这种机制来开发它,或者也可以通过计数信号量来完成。

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

【问题讨论】:

  • @LouisWasserman,可能不是很多,因为他从stackoverflow.com/questions/15029703/… 给他的答案中复制了它。但你并没有提供太多帮助,因为这几乎是我看到你在任何地方发布的唯一评论。

标签: java multithreading java.util.concurrent


【解决方案1】:

我们认为每对线程 Tw, Ts(例如 Tw)都在等待 Ts 开始其工作。在您的设置中,有 2 个这样的对:

T1, T3
T2, T1

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

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

当然,您必须删除 join 调用和相关基础架构。

由于您的问题标题询问了闩锁的实现,我们简单地说,可以使用在0 初始化的Semaphore 产生相同的语义,其中countDown 实际上是信号量的release,而await 将是该信号量的acquire

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 的类似实现留给读者作为练习。

【讨论】:

  • 能否请您提供此实现的代码,以便我能够完全理解它,提前谢谢
  • 请贴出信号量的代码,这将是一个很好的 8 帮助理解
  • 这就是您将获得的所有 asaimc。我建议您在提出更多问题之前尝试阅读常见问题解答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多