首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解CompletableFuture的简单实现

理解CompletableFuture的简单实现
EN

Stack Overflow用户
提问于 2020-08-17 14:19:04
回答 2查看 190关注 0票数 2

考虑从这篇文章获取的以下代码。为了学习目的,它实现了类似于CompletableFuture的东西。

这是get()WaitingFuture函数

代码语言:javascript
复制
@Override
public V get() throws ExecutionException {
    this.thread = Thread.currentThread();
    LockSupport.park(this);

    if (throwable != null) {
        throw new ExecutionException(throwable);
    }

    return result;
}

这是run()RunnableWaitingFuture函数

代码语言:javascript
复制
@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)之后被调用,留下线程永远停在那里。

这是真的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-17 16:06:28

park()/unpark()不同于wait/notify,因为如果unparkpark()之前被调用,那么信号不会丢失。

然而,它仍然只是一个不计算unpark被调用的频率的一点,所以假设所有调用都将完美配对仍然是错误的。

此外,park将在中断时默默地返回,甚至允许伪造返回,这意味着没有任何理由。

换句话说,即使从park()返回也不能保证条件已经满足。就像其他通知机制一样,在循环中使用它是没有办法的。

引用的代码更糟糕,因为它对thread变量有另一个竞争条件。没有保证它是在另一个线程读取它以通知它的时候写的。

票数 4
EN

Stack Overflow用户

发布于 2020-08-17 15:55:03

是。

代码语言:javascript
复制
LockSupport.park(this);

应该用这样的东西代替

代码语言:javascript
复制
while (!waitingFuture.finished) {
    LockSupport.park(this);
}

通常,LockSupport.park的特性太低,为了可靠性,应该使用Object::waitCondition::await

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63452789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档