根据javadoc,Executor
的实现必须符合以下条件:
内存一致性影响:在将Runnable对象提交给执行程序之前,在线程( A )中执行的操作发生在其执行开始之前,可能在另一个线程( B )。
由于我的英语不好,所以出现了一些包装,我不清楚在 B 和随后提交的另一个潜在线程 C 之间可以保证哪种内存一致性关系(如果有的话)由 A 发送给同一执行人。我希望以下示例可以澄清我的疑问。
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
class ExecutorTestClass {
int a = 1;
volatile boolean isDone = false;
MyRunnable mr1 = new MyRunnable("One");
MyRunnable mr2 = new MyRunnable("Two");
class MyRunnable implements Runnable {
private final String name;
MyRunnable(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + ": " + ExecutorTestClass.this.a++);
isDone = true; // signal that addition has been performed
while (true) {
try {
Thread.sleep(5); // busy thread
} catch (InterruptedException e) {
}
}
}
}
public static void main(String[] args) {
ExecutorTestClass emc = new ExecutorTestClass();
Executor executor = Executors.newFixedThreadPool(2);
executor.execute(emc.mr1); // run the first MyRunnable
while (!emc.isDone) {
} // when stop spinning emc.a == 2 for this thread
executor.execute(emc.mr2); // is emc.a == 2 guaranteed?
}
}
是否确保emc.a == 2
用于执行emc.mr2.run()
的线程? (在我的测试中,这始终是正确的,但是...是的,它们是测试)
如果没有,那么官方API中是否有接口可以确保emc.a == 2
?
答案 0 :(得分:0)
不,不能保证,因为您在一个线程中更改了emc.a
的值,但从另一个线程提交了Runnable
。如果在将值设置为2之后从第一个可运行对象提交第二个可运行对象,则JavaDoc的内存一致性效果将适用。
但是在您的示例中,即使不考虑JavaDoc的注释,使用volatile
变量isDone
也会达到目的。
由于您先递增emc.a
,然后将新值设置为isDone
,然后检查isDone
,这将在建立之前发生关系,第二个可运行对象将始终看到更新后的值。