我一直在浏览启动三个线程的程序并打印它们的相应值,以便首先执行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();
}
}
答案 0 :(得分:1)
我们认为每对线程Tw, Ts
(例如Tw
)都在等待Ts
开始工作。在您的设置中,有2对这样的对:
T1, T3
T2, T1
对于每一对,我们将创建一个CountDownLatch
,并将其提供给该对中的每个线程。然后Tw
会在开始工作前致电await
,Ts
会在自己工作结束时致电countDown
。
由于T1
属于两个对,因此它将同时接收两个锁存器。但是,在第一种情况下,T1
是一个等待线程,而在第二种情况下,T1
是一个信令线程,因此必须相应地修改其代码。
当然,您必须删除join
来电及相关基础设施。
由于你的问题标题询问了闩锁的实现,我们简单地说,使用在Semaphore
初始化的0
可以生成相同的语义,其中countDown
实际上是{信号量的{1}},而release
将是该信号量的await
。
acquire
建议的示例实现使用辅助runnable来处理锁存过程,从而允许我们使用这些runnable来组合每个任务,而不是为每个特定情况派生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
的类似实现留给读者练习。