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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程并发之原子性(六)

發布時間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程并发之原子性(六) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在網上找到好多的多線程關于原子性的例子,說的都不是非常的明確,對于剛學習多線程的新手而言很容誤導學員,在這里,我通過多個例子對多線程的原子性加以說明。

?

例子一:傳統技術自增

package face.thread.volatilep;public class Counter2 {private int count = 0; public synchronized void inc() {count = count + 1;}public static void main(String[] args) {//同時啟動1000個線程,去進行i++計算,看看實際結果final Counter2 c = new Counter2();for (int i = 0; i < 1000; i++) {new Thread(new Runnable() {@Overridepublic void run() {c.inc();}}).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//這里每次運行的值都有可能不同,可能為1000System.out.println("運行結果:Counter.count=" + c.count);} }

以上代碼打印的結果偶爾會等于1000,基本上都會有一些誤差,原因是線程執行的順序無法保證的,很可能在新建的1000個線程還沒有執行完,我們的代碼

System.out.println("運行結果:Counter.count=" + Counter.count);

就已經執行完了,要想解決這個問題很簡單,那就是在最后一句println之前在線程睡眠一段時間,比如睡眠2秒鐘。等1000個線程執行完了,在打印"

"運行結果:Counter.count=" + Counter.count";

?

還可以借助于線程輔助類解決,在這里就舉例一個最簡單的例子展示:

?

package face.thread.volatilep;import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier;public class Counter3 {int count =0; public synchronized void inc() {count++;}public static void main(String[] args) {//同時啟動1000個線程,去進行i++計算,看看實際結果final Counter3 c = new Counter3();final CyclicBarrier cy = new CyclicBarrier(10000, new Runnable() {public void run() {//這里每次運行的值都有可能不同,可能為1000System.out.println("運行結果:Counter.count=" + c.count);}});for (int i = 0; i < 10000; i++) {new Thread(new Runnable() {@Overridepublic void run() {c.inc();try {cy.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}).start();}} }

?


例子二:原子性自增

原子是世界上的最小單位,具有不可分割性。比如 a=0;(a非long和double類型) 這個操作是不可分割的,那么我們說這個操作時原子操作。再比如:a++; 這個操作實際是a = a + 1;是可分割的,所以他不是一個原子操作。非原子操作都會存在線程安全問題,需要我們使用同步技術(sychronized)來讓它變成一個原子操作。一個操作是原子操作,那么我們稱它具有原子性。Java的concurrent包下提供了一些原子類,我們可以通過閱讀API來了解這些原子類的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。 因為原子性是線程安全的,所以關于原子性自增是不需要傳統的加鎖技術的,具體看代碼: package face.thread.volatilep;import java.util.concurrent.atomic.AtomicInteger;public class CounterNew2{AtomicInteger count = new AtomicInteger(0);public void increment() {count.getAndIncrement();}public int getCount() {return count.get();}public static void main(String[] args) {final CounterNew2 cn = new CounterNew2();for(int i = 0 ; i < 10000;i++){new Thread(new Runnable() {public void run() {cn.increment();}}).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("count最終返回值:" + cn.getCount());} } 運行結果也是:10000

轉載于:https://www.cnblogs.com/chen1-kerr/p/6900051.html

總結

以上是生活随笔為你收集整理的多线程并发之原子性(六)的全部內容,希望文章能夠幫你解決所遇到的問題。

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