【发布时间】:2013-08-18 02:20:20
【问题描述】:
在并发方面我是新手,在发现问题时不确定自己,我正在查看一个相当成熟的代码库,发现以下代码(为简洁而编辑),我认为这些代码容易受到数据竞争的影响:
public class Example extends Thread {
boolean condition = false;
public void run () {
while (true) {
synchronized (this) {
try {
while( condition ) wait();
}
catch (InterruptedException e) { /*for brevity*/ }
}
// non-blocking computation
}
}
public void setTrue () { condition = true; }
public void setFalse () {
synchronized (this) {
condition = false;
this.notifyAll();
}
}
}
据我了解condition 必须是易失性的,因为即使使用同步块,编译器也不会发出任何内存屏障;如果它是在setTrue 中的condition 的易失性存储,编译器将发出StoreEnter.
我是否认为上述内容容易受到数据竞争的影响?如果是这样,我怎么能通过一个例子来见证数据竞赛(而不是简单地知道 JMM 提供的保证)。使用线程在循环中随机调用 setTrue 的简单测试不会发现数据竞争。
另外,我认为在这里使用 notifyAll 是多余的,因为要检查一个条件并且只有一个线程会等待它,对吧?
谢谢。
【问题讨论】:
-
除非你真的有理由,否则不要扩展
Thread类。最好实现 Runnable 接口并将类的实例提供给 Thread 构造函数。
标签: java concurrency volatile java.util.concurrent