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個線程執(zhí)行了5000次++操作,為什么結(jié)果是線程不安全的
1 回答
已采納

一凡
TA貢獻43條經(jīng)驗 獲得超8個贊
++count的操作實際是三個操作
1 cpu從內(nèi)存讀取count
2 cpu內(nèi)部更改count
3 cpu寫入count
多線程的時候,可能會有100個線程同時讀取的值都是0,那么他們++之后寫回去當然就是1,而不是100 。同時在cpu寫入的時候,也不是實時寫入,而是在cpu高速緩存內(nèi),所以各個線程內(nèi)的count數(shù)值是不一樣的。
要保證讀寫一致性,需要加入同步的方法來操作。這里只是對count一個變量做++運算,可以用CAS或者鎖。當然JAVA里面的變量屬性 volatile 也是可以保證單個數(shù)字更新同步的效果。
這里?new
?Semaphore(1); 也可以限制同時只能有一個線程進入++count操作,也能達到線程安全的目的。
添加回答
舉報
0/150
提交
取消