我想运行多个线程。我清楚地让比赛条件,并能够解决这个问题如下:即使在同步后竞态条件
final Data data = new Data();
for (int i = 0; i < numberOfThreads; i++) {
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//using this sync block to stop the race condition
synchronized (data){
final int value = data.getValue();
data.setValue(value + 1);
}
}
});
thread.start();
}
但我不希望这个块上同步,而是要在数据类来处理它。所以我删除了上面的同步块,而是按如下方式同步了Data类中的get和set方法,但这仍然会导致竞争条件。为什么这个问题即使我已经同步了他们?
public class Data {
private int value;
public synchronized int getValue(){
return this.value;
}
public synchronized void setValue(int num){
this.value = num;
}
}
因为没有额外的同步块,多个线程可以同时调用getValue(),将其加1,然后再写入相同的值,尽管它们应该增加了getValue()被调用的次数。 – markspace
竞争条件究竟如何体现? 此外,如果意图是让线程安全增量,为什么不使用[AtomicInteger](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger。 html)? –
这是双重检查锁定的变体(https://en.wikipedia.org/wiki/Double-checked_locking) - 如答案所示,您正在获取并单独设置。 – stdunbar