为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这段断码是线程不安全的?

为什么这段断码是线程不安全的?

慕粉4241372 2018-05-16 10:26:02
public class ThreadTest {     private static int threadTotal = 200;     private static int clientTotal = 5000;     private static int count = 0;     public static void main(String[] args) throws InterruptedException {         ExecutorService executorService = Executors.newCachedThreadPool();         final Semaphore semaphore = new Semaphore(threadTotal);         final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);         for (int i = 0; i < clientTotal; i++) {             executorService.execute(() -> {                 try {                     semaphore.acquire();                     ++count;                     semaphore.release();                     countDownLatch.countDown();                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             });         }         countDownLatch.await();         System.out.println(count);         executorService.shutdown();     } }这段代码操作的是一个static 变量,5000个线程执行了5000次++操作,为什么结果是线程不安全的
查看完整描述

1 回答

已采纳
?
一凡

TA贡献43条经验 获得超8个赞

++count的操作实际是三个操作

1 cpu从内存读取count

2 cpu内部更改count

3 cpu写入count

多线程的时候,可能会有100个线程同时读取的值都是0,那么他们++之后写回去当然就是1,而不是100 。同时在cpu写入的时候,也不是实时写入,而是在cpu高速缓存内,所以各个线程内的count数值是不一样的。

要保证读写一致性,需要加入同步的方法来操作。这里只是对count一个变量做++运算,可以用CAS或者锁。当然JAVA里面的变量属性 volatile 也是可以保证单个数字更新同步的效果。

这里 new Semaphore(1); 也可以限制同时只能有一个线程进入++count操作,也能达到线程安全的目的。

查看完整回答
反对 回复 2018-05-23
  • 1 回答
  • 0 关注
  • 1021 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信