您的位置:首页 > 编程语言 > Java开发

无同步的并发计数结果不对

2016-10-14 00:00 141 查看
Demo类
com.oldratlee.fucking.concurrency.WrongCounterDemo


Demo说明

主线程中开启2个任务线程执行并发递增计数。主线程最终结果检查。

问题说明

计数值不对。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.WrongCounterDemo

下面的demo即使有volatile属性也是不能保证计数器的正确性的。

public class WrongCounterDemo {
private static final int INC_COUNT = 100000000;

volatile int counter = 0;

public static void main(String[] args) throws Exception {
WrongCounterDemo demo = new WrongCounterDemo();

System.out.println("Start task thread!");
Thread thread1 = new Thread(demo.getConcurrencyCheckTask());
thread1.start();
Thread thread2 = new Thread(demo.getConcurrencyCheckTask());
thread2.start();

thread1.join();
thread2.join();

int actualCounter = demo.counter;
int expectedCount = INC_COUNT * 2;
if (actualCounter != expectedCount) {
// 在我的开发机上,几乎必现!即使counter上加了volatile。(简单安全的解法:使用AtomicInteger)
System.err.printf("Fuck! Got wrong count!! actual %s, expected: %s.", actualCounter, expectedCount);
} else {
System.out.println("Wow... Got right count!");
}
}

ConcurrencyCheckTask getConcurrencyCheckTask() {
return new ConcurrencyCheckTask();
}

private class ConcurrencyCheckTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < INC_COUNT; ++i) {
++counter;
}
}
}
}

接下来使用AtomicInteger做计数器,就可以不用volatile变量了。

public class WrongCounterDemo {
private static final int INC_COUNT = 100000000;

AtomicInteger counter = new AtomicInteger(0);

public static void main(String[] args) throws Exception {
WrongCounterDemo demo = new WrongCounterDemo();

System.out.println("Start task thread!");
Thread thread1 = new Thread(demo.getConcurrencyCheckTask());
thread1.start();
Thread thread2 = new Thread(demo.getConcurrencyCheckTask());
thread2.start();

thread1.join();
thread2.join();

int actualCounter = demo.counter.intValue();
int expectedCount = INC_COUNT * 2;
if (actualCounter != expectedCount) {
// 在我的开发机上,几乎必现!即使counter上加了volatile。(简单安全的解法:使用AtomicInteger)
System.err.printf("Fuck! Got wrong count!! actual %s, expected: %s.", actualCounter, expectedCount);
} else {
System.out.println("Wow... Got right count!");
}
}

ConcurrencyCheckTask getConcurrencyCheckTask() {
return new ConcurrencyCheckTask();
}

private class ConcurrencyCheckTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < INC_COUNT; ++i) {
counter.incrementAndGet();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  atomicInteger java 并发