我的期望是,程序将返回输出"1000“。
但是,每次程序执行不同的输出时。
计数器类的增量()方法已经同步。只有这样才能避免相互竞争的读数吗?
怎样才能正确计算1000次增量呢?
package app;
public class Counter {
private Integer value;
public Counter(int initialValue) {
value = initialValue;
}
public synchronized void increment() {
value = value + 1;
}
public int getValue() {
return value;
}
}
package app;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
Counter contador = new Counter(0);
ExecutorService executor = Executors.newFixedThreadPool(10);
for(int i = 0; i < 1000; i++) {
executor.submit(() -> {
contador.increment();
});
}
System.out.println(contador.getValue());
}
}发布于 2017-10-26 15:29:20
您的主要方法应该是这样的:
public static void main(String[] args) {
Counter contador = new Counter(0);
ExecutorService executor = Executors.newFixedThreadPool(10);
for(int i = 0; i < 1000; i++) {
executor.submit(() -> {
contador.increment();
});
}
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
}
System.out.println(contador.getValue());
}发布于 2017-10-26 15:28:31
你的逻辑很好。
问题是在线程完成增量之前打印计数器的值。
将代码更改为:
for(int i = 0; i < 1000; i++) {
executor.submit(() -> {
contador.increment();
});
}
executor.shutdown(); //Shut down the executor
//Wait until the threads have stopped. A maximum of 1 minute is more than enough
executor.awaitTermination(1, TimeUnit.MINUTES);
System.out.println(contador.getValue()); //prints 1000发布于 2017-10-26 15:25:39
对您的问题的答案是,您没有等待您的所有Runnables完成之前,打印的价值康塔多。
因此,有时只调用20个增量调用,有时50个调用,等等。
编辑:
仔细看,我认为您的线程安全有一个潜在的问题。您已经同步了增量值。getValue方法是否匹配?
例如,如果线程A正在递增,那么线程B在调用getValue时应该看到什么?它应该看到旧的值,还是应该等到线程A完成后才得到最新的值?
https://stackoverflow.com/questions/46958118
复制相似问题