AtomicLong并发计数时输出结果不符合预期问题咨询
问题原因
你的AtomicLong使用没有错误,原子类的incrementAndGet()本身确实可以保证计数的线程安全,出现999这类结果和原子类无关,是线程池使用逻辑的疏漏:
shutdown()方法不会等待已提交到线程池的任务全部执行完成,它只会停止接收新任务,之前提交的任务会继续异步执行- 你在调用
shutdown()后立刻读取计数器值,此时大概率还有部分自增任务没有执行完,读到的就是累加过程中的中间值,才会出现小于1000的结果。
修复方法
在shutdown()之后调用awaitTermination()方法,阻塞等待线程池内所有已提交任务执行完毕,再读取计数即可。修正后的完整代码如下:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class AtomicTest { public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); int count = 1000; ExecutorService executorService = Executors.newFixedThreadPool(count); for(int i=0;i<count;i++) { executorService.submit(counter::inc); } executorService.shutdown(); // 等待所有任务执行完成,设置合理超时时间即可 executorService.awaitTermination(1, TimeUnit.MINUTES); System.out.println(counter.getValue()); } } class Counter { private AtomicLong counter = new AtomicLong(); public void inc() { counter.incrementAndGet(); } public void dec() { counter.decrementAndGet(); } public long getValue() { return counter.get(); } }
修正后多次运行结果会稳定为1000,不会再出现小于1000的情况。
内容的提问来源于stack exchange,提问作者Adithya
相关产品推荐
相关产品推荐

