Bri*_*ian 3 java multithreading completable-future spring-async
我有一个调用两个单独线程的线程。CompletableFuture它向这两个子线程传递相同的内容。如果.get()同时在这两个线程中调用,我会遇到任何类型的并发问题吗?
CompletableFuture?.get()?作为一个具体的例子,在下面的代码中,假设完成cfInput.get()后返回的对象没有发生任何变化,两个线程是否有可能打印不同的值?cfInput
public void mainClass(CompletableFuture<ObjA> cfInput){\n class1.doAsync1(cfInput);\n class2.doAsync2(cfInput);\n}\n\n@Async\npublic void doAsync1(CompletableFuture<ObjA> cfInput){\n //logic\n System.out.println(cfInput.get().getObjB().getBlah());\n //logic\n}\n\n@Async\npublic void doAsync2(CompletableFuture<ObjA> cfInput){\n //logic\n System.out.println(cfInput.get().getObjB().getBlah());\n //logic\n}\n\npublic class ObjA{\n private ObjB objB;\n public ObjB getObjB();\n public void setObjB();\n}\npublic class ObjB{\n private String blah;\n public String getBlah();\n public void setBlah();\n}\nRun Code Online (Sandbox Code Playgroud)\n
CompletableFuture本质上是线程安全的您可以简单地假设这一点,因为此类被设计为在多线程上下文中使用,但是在包的描述java.util.concurrent中更清楚地指定了这一点:
\n\n内存一致性属性
\nJava 语言规范第 17 章定义了内存操作(例如共享变量的读写)的happens-before关系。仅当写入操作发生在读取操作之前时,才保证一个线程的写入结果对另一个线程的读取可见。\n[\xe2\x80\xa6]\n
\njava.util.concurrent中及其中所有类的方法子包将这些保证扩展到更高级别的同步。尤其:\n
\n- [\xe2\x80\xa6]
\n- 在通过另一个线程检索结果之后,由 Future 表示的异步计算所采取的操作发生在操作之前。
\nFuture.get()
因此,这意味着线程在完成 future 之前执行的任何写入对于调用该 future 的任何其他线程都是可见的get()(即它 \xe2\x80\x9c发生在\xe2\x80\x9d 之前)。
\xe2\x80\xa6 也不受 \xe2\x80\x9c 保护\xe2\x80\x9dCompletableFuture
尽管CompletableFuture它本身是线程安全的,并且为写入的可见性提供了一些保证,但它并不能使您的对象成为线程安全的。
例如,如果您修改 返回的对象,则在您进入另一个发生之前CompletableFuture.get()关系之前,不保证这些更改对任何其他线程都可见。因此,您可能需要额外的同步来强制该对象的线程安全。
| 归档时间: |
|
| 查看次数: |
2321 次 |
| 最近记录: |