我正在做一些思想实验,这是我的 MyRunnable
类:
class MyRunnable implements Runnable {
private final Integer mNumber;
private final CompleteHandler<Integer> mCallback;
public MyRunnable(Integer i, CompleteHandler<Integer> ch) {
mNumber = i;
mCallback = ch;
}
public void run() {
int sum = 0;
for (int i = 1; i <= mNumber; i++) {
sum += i;
}
mCallback.onFinished(sum);
}
}
这将由我在主线程上的 execute()
方法下创建的后台线程执行
public class Demo implements CompleteHandler<Integer>{
public static void main(String[] args) {
Demo d = new Demo();
d.execute();
}
@Override
public void onFinished(Integer i) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName); // thread-0
}
public void execute() {
MyRunnable mr = new MyRunnable(10, this);
Thread t = new Thread(mr);
t.start();
}
}
如您所见,任务完成时,MyRunnable
调用onFinished()
。有什么办法可以让后台线程在主线程上调用它吗?我知道我可以使用可调用对象做类似的事情,但现在我想知道可运行对象是否可以这样做,
谢谢
最佳答案
Johannes: Take a look at CompletableFuture...
Brendon: I'm more interested in seeing how it work on code
这是一个忽略异常问题的简单实现。 (如果它实际上不是有效的 Java 代码,请原谅我。)
class CompletableFuture<ValueType> {
private Object lock = new Object();
private boolean is_completed = false;
private ValueType completed_value;
public synchronized void complete(ValueType v) {
completed_value = v;
is_completed = true;
notifyAll();
}
public synchronized ValueType await() {
while (! is_completed) {
wait();
}
return completed_value;
}
}
这个想法是,客户端线程创建一个 CompletableFuture 实例,cf
,并以某种方式将其传递给服务器线程,可能还有其他参数告诉服务器线程要做什么。然后客户端线程就会去执行其他不相关的事情。
同时,服务器线程执行其工作,最终生成结果r
,然后调用cf.complete(r)
.
在某个时刻,客户端线程完成了它正在执行的其他操作,现在它需要结果,因此它调用 cf.await()
。此时会发生以下两种情况之一:
- 服务器已经设置了 is_completed 标志,在这种情况下,客户端会立即获取结果,或者
- 服务器尚未完成,因此客户端进入
wait()
循环等待。
当您查看应用程序代码时,您通常不会看到客户端线程创建 Future 对象或将其传递给其他线程的部分。当客户端向线程池提交任务时,这通常是在库调用内部完成的。
关于java - 如何让Java runnable从主线程而不是后台线程调用回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58225483/