关于倒计时闩锁的实现 [英] Regarding countdown latch implementation

查看:61
本文介绍了关于倒计时闩锁的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

此相关问题的答案:

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

推荐答案

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

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

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

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.

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

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.

当然,您必须删除join调用和相关的基础结构.

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

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

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

建议的示例实现使用辅助可运行对象来处理闩锁过程,因此允许我们使用这些可运行对象来组成每个任务,而不是针对每种特定情况派生Printer类(我们至少保存一个类).

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).

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

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

这篇关于关于倒计时闩锁的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆