问题如下:
如下所示同时启动三个线程:
t1.start();
t2.start();
t3.start();
第一个线程(t1)的输出应该是第二个线程(t2)的输入,第二个线程(t2)的输出应该是第三个线程(t3)的输入。
你能告诉我逻辑吗?我知道我们可以使用wait和notify方法。但我可以获得实现此输出的算法或逻辑吗?
答案 0 :(得分:0)
这是一个帮助类。它在单例辅助类中实现了两个资源锁。
让每个线程使用ResourceLock.getInstance()
获取实例。让线程2调用getResource1()
并等待线程1完成并将其输出放在setResource1()
中。这将释放锁定和线程2对getResource1()
的调用返回。
重复第2和第2次线程3
在没有超时的情况下调用挂起函数并不是一个好主意。因此,超时为10秒,根据您的需要进行编辑。
package com.madinsweden.test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class ResourceLock {
protected static final int TIMEOUT = 10000; //ms
private CountDownLatch mLock1;
private CountDownLatch mLock2;
private Object mObject1;
private Object mObject2;
private static ResourceLock mInstance;
private ResourceLock() {
mLock1 = new CountDownLatch(1);
mLock2 = new CountDownLatch(1);
}
public static ResourceLock getInstance() {
if (null == mInstance) {
mInstance = new ResourceLock();
}
return mInstance;
}
public void setObject1(Object o) {
mObject1 = o;
mLock1.countDown();
}
public Object getResource1() {
try {
mLock1.await(TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException("Timeout of resource lock 1");
}
return mObject1;
}
public void setObject2(Object o) {
mObject2 = o;
mLock2.countDown();
}
public Object getResource2() {
try {
mLock2.await(TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException("Timeout of resource lock 2");
}
return mObject2;
}
}
答案 1 :(得分:0)
我建议您使用ExecutorServices。这意味着更容易在线程之间传递工作。
// fields
ExecutorServices service1 = ...
ExecutorServices service2 = ...
ExecutorServices service3 = ...
// Task1 submits to service2
service1.submit(new Task1());
// service2 submits to service3
答案 2 :(得分:0)
有几种方法可以做到这一点。正如Jon指出的那样,以这种方式运行线程没有意义,因为你导致我们阻塞其他线程的输出,实际上没有实现并行化。
我的“首选”解决方案是使用ExecutorService
,如彼得所提到的,虽然有点不同。这是一种天真的方法。
ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<String> output1 = executor.submit(new Callable<String>() {
@Override public String call() {
// do Something
return "a String from Task #1";
}
});
final Future<String> output2 = executor.submit(new Callable<String>() {
@Override public String call() throws Exception{
// do Something
// Wait for the output of the above task using `Future.get()`.
return output1.get() + ", a String from Task #2";
}
});
Future<String> output3 = executor.submit(new Callable<String>() {
@Override public String call() throws Exception{
// do Something
return output2.get() + ", a String from Task #3";
}
});
System.err.print("Output from 3rd task: " + output3.get());
使用线程执行此操作的其他方法:共享阻塞数据结构(例如,线程之间的BlockingQueue
以安全地发布结果。如果没有传递结果并且只需要终止其他线程的信号,则使用{ {1}} es。