日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程详解(17)-原子量

發布時間:2025/3/21 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程详解(17)-原子量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

所謂的原子量即操作變量的操作是“原子的”,該操作不可再分,因此是線程安全的。

????????為何要使用原子變量呢,原因是多個線程對單個變量操作也會引起一些問題。在Java5之前,可以通過volatile、synchronized關鍵字來解決并發訪問的安全問題,但這樣太麻煩。

????????Java5之后,專門提供了用來進行單變量多線程并發安全訪問的工具包java.util.concurrent.atomic,其中的類也很簡單。

????????下面給出一個反面例子(切勿模仿):

import?java.util.concurrent.ExecutorService;?? import?java.util.concurrent.Executors;?? import?java.util.concurrent.atomic.AtomicLong;??/**?*?Java線程:新特征-原子量?*/?? public?class?Test?{??public?static?void?main(String[]?args){??//創建一個線程池??ExecutorService?pool?=?Executors.newFixedThreadPool(2);??Runnable?t1?=?new?MyRunnable("張三",?2000);??Runnable?t2?=?new?MyRunnable("李四",?3600);??Runnable?t3?=?new?MyRunnable("王五",?2700);??Runnable?t4?=?new?MyRunnable("老張",?600);??Runnable?t5?=?new?MyRunnable("老牛",?1300);??Runnable?t6?=?new?MyRunnable("胖子",?800);??//執行各個線程??pool.execute(t1);??pool.execute(t2);??pool.execute(t3);??pool.execute(t4);??pool.execute(t5);??pool.execute(t6);??//關閉線程池??pool.shutdown();??}?? }?? class?MyRunnable?implements?Runnable{??private?static?AtomicLong?aLong?=newAtomicLong(10000);????????//原子量,每個線程都可以自由操作??private?String?name;??????????//操作人??private?int?x;????????????????//操作數額??MyRunnable(String?name,?int?x)?{??this.name?=?name;??this.x?=?x;??}??public?void?run()?{??System.out.println(name?+?"執行了"?+?x?+",當前余額:"?+?aLong.addAndGet(x));??}?? }??


????????多次執行結果:

李四執行了3600,當前余額:13600?? 王五執行了2700,當前余額:16300?? 老張執行了600,當前余額:16900?? 老牛執行了1300,當前余額:18200?? 胖子執行了800,當前余額:19000?? 張三執行了2000,當前余額:21000??

?

張三執行了2000,當前余額:12000?? 王五執行了2700,當前余額:14700?? 老張執行了600,當前余額:15300?? 老牛執行了1300,當前余額:20200?? 李四執行了3600,當前余額:18900?? 胖子執行了800,當前余額:21000??

?

張三執行了2000,當前余額:12000?? 王五執行了2700,當前余額:14700?? 李四執行了3600,當前余額:18300?? 老牛執行了1300,當前余額:20200?? 胖子執行了800,當前余額:21000?? 老張執行了600,當前余額:18900??


????????從運行結果可以看出,雖然使用了原子量,但是程序并發訪問還是有問題,那究竟問題出在哪里了?

????????這里要注意的一點是,原子量雖然可以保證單個變量在某一個操作過程的安全,但無法保證你整個代碼塊,或者整個程序的安全性。因此,通常還應該使用鎖等同步機制來控制整個程序的安全性。

????????下面是對這個錯誤修正:

import?java.util.concurrent.ExecutorService;?? import?java.util.concurrent.Executors;?? import?java.util.concurrent.atomic.AtomicLong;?? import?java.util.concurrent.locks.Lock;?? import?java.util.concurrent.locks.ReentrantLock;??/**?*?Java線程:新特征-原子量?*/?? public?class?Test?{??public?static?void?main(String[]?args){??//創建一個線程池??ExecutorService?pool?=?Executors.newFixedThreadPool(2);??Lock?lock=new?ReentrantLock(false);??Runnable?t1?=?new?MyRunnable("張三",?2000,lock);??Runnable?t2?=?new?MyRunnable("李四",?3600,lock);??Runnable?t3?=?new?MyRunnable("王五",?2700,lock);??Runnable?t4?=?new?MyRunnable("老張",?600,lock);??Runnable?t5?=?new?MyRunnable("老牛",?1300,lock);??Runnable?t6?=?new?MyRunnable("胖子",?800,lock);??//執行各個線程??pool.execute(t1);??pool.execute(t2);??pool.execute(t3);??pool.execute(t4);??pool.execute(t5);??pool.execute(t6);??//關閉線程池??pool.shutdown();??}?? }?? class?MyRunnable?implements?Runnable?{??private?static?AtomicLong?aLong?=newAtomicLong(10000);???//原子量,每個線程都可以自由操作??private?String?name;??????????//操作人??private?int?x;????????????????//操作數額??private?Lock?lock;??MyRunnable(String?name,?int?x,Lock?lock)?{??this.name?=?name;??this.x?=?x;??this.lock=lock;??}??public?void?run()?{??lock.lock();??System.out.println(name?+?"執行了"?+?x?+",當前余額:"?+?aLong.addAndGet(x));??lock.unlock();??}?? }??


????????執行結果:

張三執行了2000,當前余額:12000?? 王五執行了2700,當前余額:14700?? 老張執行了600,當前余額:15300?? 老牛執行了1300,當前余額:16600?? 胖子執行了800,當前余額:17400?? 李四執行了3600,當前余額:21000??


????????這里使用了一個對象鎖,來控制對并發代碼的訪問。不管運行多少次,執行次序如何,最終余額均為21000,這個結果是正確的。

????????有關原子量的用法很簡單,關鍵是對原子量的認識,原子僅僅是保證變量操作的原子性,但整個程序還需要考慮線程安全的。
?

總結

以上是生活随笔為你收集整理的Java线程详解(17)-原子量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。