java.util.concurrent.Future是否线程安全?

18
我正在寻找有关 java.util.concurrent.Future 是否是线程安全的文档。例如,我能否安全地将相同的 Future 实例分配给多个线程,并且它们都会调用 Future.get(...)?
我已经测试了使用 Future 的代码,并且它似乎可以正常工作,但如果我能找到有关 Future 在这种方式下是否安全进行并发访问的文件说明,那就更好了。
谢谢。

2
本质上,这个评论与Nizet的回答相同:您可以在JDK javadoc中查看内存一致性保证:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html#package_description - Victor Sorokin
将“由Future表示的异步计算采取的操作发生在通过Future.get()检索结果之后的操作之前”解读为真实的,是否可以将其应用于许多其他线程以及单个其他线程? “另一个线程”字面上表示与单个线程相反。当然,未来的实现者似乎必须费尽心思才能使其对许多线程失效并对一个线程有效,因此我强烈怀疑这在现实中是安全的。 - S42
1
是的,因为每次调用Future.get()都将在“happens-before”保证下进行。这是因为每个调用都编译为涉及一种或另一种形式的http://en.wikipedia.org/wiki/Memory_barrier的相同汇编。 - Victor Sorokin
请注意,所有线程都将在等待get()结果时阻塞。如果get()的结果是可变的,则所有线程可能无法观察相同的值。 - Greg Mattes
2个回答

12

鉴于将来的使用意图是由多个线程使用的(至少一个提交结果的线程和一个设置结果的线程),并且考虑到文档规定get调用后的行为与异步计算之间存在happen-before关系,我会假设其实现是线程安全的(至少标准实现是这样的)。


2
我强烈倾向于同意实际上它几乎肯定是安全的,因为在两个线程之间工作的 happen-before 线程安全通常也适用于 N 个线程,但是当保证的措辞暗示单个其他线程时,我不确定是否可以将 happen-before 解释为对多个线程的保证。尽管有这样的小保留,但我仍然投票支持您的评论,因为它似乎是目前最好的答案。 - S42
2
@S42 你对措辞的理解太过字面了。在Java中,一对线程之间绝对没有特殊的通信方式;所有线程都通过同步内存进行通信,并且它对所有线程都是平等可用的。 - toto2

8

如果您正在使用由ExecutorService返回的Future,那么它们是线程安全的。由于Future是一个接口,因此接口的创建者无法保证所有实现都是线程安全的。

Nizet提出了一个很好的观点。文档中建议Future接口的实现应该是线程安全的,如果没有使实现线程安全,则会违反Future的契约。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接