Future#isDone返回true时,异步线程操作是否满足happens-before关系?
关于Java Future#isDone的两个并发问题拆解
问题1:异步任务执行的操作,是否会在返回true的Future#isDone调用之前具备happens-before关系?
当然会!按照Java内存模型(JMM)的官方规范,当Future#isDone()返回true时,该异步任务执行的所有操作,都happens-before于这个isDone()调用返回true的动作。简单说就是,异步任务里的代码必须全部执行完,isDone()才会返回true,绝对不会出现任务还在运行,isDone()就提前返回true的情况。
问题2:isDone返回true后,后续代码能否保证看到异步任务的操作结果?
你这个问题换个直白的说法就是:如果isDone()返回true,那之后的代码是不是一定能拿到异步任务执行后的结果?会不会出现isDone()说任务完成了,但后续代码看不到任务修改的数据?
答案是完全可以保证!因为Future#isDone()返回true这个动作,和你在当前线程里紧接着执行的代码之间,会建立明确的happens-before关系。用顺序链来表示就是:
异步任务的所有操作 → isDone()返回true → 当前线程后续执行的代码
这条链在JMM里是被严格保障的,不存在乱序或者可见性漏洞。
举个实际的代码例子你就懂了:
ExecutorService executor = Executors.newSingleThreadExecutor(); AtomicInteger num = new AtomicInteger(0); Future<?> future = executor.submit(() -> num.set(100)); // 循环等待任务完成 while (!future.isDone()) { Thread.yield(); } // 这里打印出来的num一定是100,绝不会是0 System.out.println(num.get());
这个例子里,只要退出循环(也就是isDone()返回true),后续的num.get()必然能拿到异步任务设置的100,不会出现数据不一致的情况。
内容的提问来源于stack exchange,提问作者jacobm
相关产品推荐
相关产品推荐

