在“Future<?>”任务完成后检查字段是否安全?
Is it safe to check fields after `Future<?>` tasks are finished?
在成功调用 future.get()
后检查由 Future<?>
中执行的任务修改的字段是否安全?
(是否保证设置完成,我看到的是新值?)
我会在调用 future.get()
.
的同一线程上检查该字段
或者我应该只使用 future.get()
的 return 值而不应该期望它像这样工作吗?
示例:
class MyData {
private int a;
public void setA(int a) { this.a = a; }
public int getA() { return a; }
}
public class MainClass {
public static void main(String[] args) {
final Executor executor = Executors.newFixedThreadPool(15);
final List<MyData> objects = Arrays.asList(new MyData(), new MyData() /* ... */);
final Future<Void> future1 = CompletableFuture.supplyAsync(() -> { objects.get(0).setA(1); return null; }, executor);
final Future<Void> future2 = CompletableFuture.supplyAsync(() -> { objects.get(1).setA(2); return null; }, executor);
/* ... */
a.get();
b.get();
/* ... */
// Is it safe here to check the `a` field of the objects?
assert objects.get(0).getA() == 1;
assert objects.get(1).getA() == 2;
}
}
正如 Future#get()
的文档所说:
Waits if necessary for the computation to complete, and then retrieves its result.
因此一旦调用 Future.get()
方法就可以完全安全地执行断言,因为届时值将被解析。
Future
的 javadoc 指出
Memory consistency effects: Actions taken by the asynchronous
computation happen-before actions following the corresponding
Future.get()
in another thread.
因为 get
只会 return 当相应的计算完成时(setA
调用和 return
),该计算通过 是可见的在调用 get
之后与任何代码发生前 关系。您对 getA
的调用发生在 Future#get
之后,因此它将看到发生在它之前的 setA
的结果。
在成功调用 future.get()
后检查由 Future<?>
中执行的任务修改的字段是否安全?
(是否保证设置完成,我看到的是新值?)
我会在调用 future.get()
.
或者我应该只使用 future.get()
的 return 值而不应该期望它像这样工作吗?
示例:
class MyData {
private int a;
public void setA(int a) { this.a = a; }
public int getA() { return a; }
}
public class MainClass {
public static void main(String[] args) {
final Executor executor = Executors.newFixedThreadPool(15);
final List<MyData> objects = Arrays.asList(new MyData(), new MyData() /* ... */);
final Future<Void> future1 = CompletableFuture.supplyAsync(() -> { objects.get(0).setA(1); return null; }, executor);
final Future<Void> future2 = CompletableFuture.supplyAsync(() -> { objects.get(1).setA(2); return null; }, executor);
/* ... */
a.get();
b.get();
/* ... */
// Is it safe here to check the `a` field of the objects?
assert objects.get(0).getA() == 1;
assert objects.get(1).getA() == 2;
}
}
正如 Future#get()
的文档所说:
Waits if necessary for the computation to complete, and then retrieves its result.
因此一旦调用 Future.get()
方法就可以完全安全地执行断言,因为届时值将被解析。
Future
的 javadoc 指出
Memory consistency effects: Actions taken by the asynchronous computation happen-before actions following the corresponding
Future.get()
in another thread.
因为 get
只会 return 当相应的计算完成时(setA
调用和 return
),该计算通过 是可见的在调用 get
之后与任何代码发生前 关系。您对 getA
的调用发生在 Future#get
之后,因此它将看到发生在它之前的 setA
的结果。