考虑以下摘自 this article 的代码.出于学习目的,它实现了类似于 CompletableFuture 的东西。
这是 WaitingFuture
的 get()
函数:
@Override
public V get() throws ExecutionException {
this.thread = Thread.currentThread();
LockSupport.park(this);
if (throwable != null) {
throw new ExecutionException(throwable);
}
return result;
}
下面是 RunnableWaitingFuture
的 run()
函数:
@Override
public void run() {
try {
waitingFuture.result = userFunction.get();
} catch (Throwable throwable) {
waitingFuture.throwable = throwable;
} finally {
waitingFuture.finished = true;
LockSupport.unpark(waitingFuture.thread);
}
}
}
问题:
在我看来,如果 run()
将在 get()
被调用之前完成,那么 LockSupport.park(this);
将被调用在 LockSupport.unpark(waitingFuture.thread)
之后,让线程永远停止。
这是真的吗?
最佳答案
park()
/unpark()
不同于wait
/notify
,因为信号不会'如果在 park()
之前调用了 unpark
,则不会丢失。
但是,仍然只有一个位没有计算 unpark
被调用的频率,因此假设所有调用都将完美配对仍然是错误的。
此外,park
将在中断时静默返回,甚至可以虚假地返回,这意味着没有任何理由。
换句话说,即使从 park()
返回也不能保证条件已经满足。就像其他通知机制一样,无法在循环中使用它。
引用的代码更糟,因为它有另一个关于 thread
变量的竞争条件。不能保证它已在另一个线程读取它以通知它的时候写入。
关于java - 理解 CompletableFuture 简单实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63452789/