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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

并发编程基础之volatile关键字的用法

發布時間:2025/5/22 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 并发编程基础之volatile关键字的用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:概念

volatile關鍵字是一個輕量級的線程同步,它可以保證線程之間對于共享變量的同步,假設有兩個線程a和b,

它們都可以訪問一個成員變量,當a修改成員變量的值的時候,要保證b也能夠取得成員變量最新的值,程序的

內存模型是這樣的,程序運行時,成員變量的值被加載到內存中,如果線程a運行時,會把變量的值拷貝到cpu分配

給a的高速緩存區,就是內存的一個副本,線程b運行時,會把變量拷貝到cpu分配給b的高速緩存區,正常情況下,

a線程修改成員變量時,會將高速緩存中的值寫入主存,然后b線程運行時讀取主存中值到緩存,但是不是強制性的,

使用volatile關鍵字就是強制性。

1:將高速緩存強制寫入主內存

2:會使b線程高速緩存標記失效

?

二:比較經典的一個示例

t1線程先啟動,然后一直打印‘i love u’,這時t2線程啟動,將flag變量的值修改為true,然后t1線程的執行終止,如果flag變量不加volatile修飾,

出現死循環的概率是存在的,但是比較低,如果加volatile,會強制t2線程修改主內存中flag的值,而且t1線程高速緩存標記會失效,可以保證

一定能夠終止t1程序的執行

/*** */ package com.day2;/*** @author Administrator**/ public class ListAdd1 {private boolean flag;public static void main(String[] args) {ListAdd1 list = new ListAdd1();//線程1Thread t1 = new Thread("t1"){public void run(){while(!list.flag){System.out.println("i love u");}}};//線程2Thread t2 = new Thread("t2"){public void run(){list.flag = true;}};t1.start();//保證t1線程先啟動try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}t2.start();}}

?

private volatile boolean flag;

  

但是volatile并不能保證操作的原子性,線程搶到cpu的時間片,修改高速緩存的值,寫入主內存這幾個過程不是原子的,

?

int i = 0;

i = i+1;

如果線程1在搶到cpu的時間片之后,還沒有修改高速緩存的值,然后線程2也讀取了主內存中緩存的值i = 0,然后執行加1,

寫入高速緩存,線程1之前讀取緩存中的值也是0,然后執行加1,寫入主內存,這樣就出現問題了,所以使用volatile不能

保證線程安全問題。

如下示例:

啟動10個線程,count初始值為0,正常情況,10個線程個循環1000次,最后的count值應該為10000,但是不是,這個值

是隨機的。

/*** */ package com.day2;/*** @author Administrator**/ public class ListAdd2 {private volatile int count;public static void main(String[] args) {ListAdd2 list = new ListAdd2();System.out.println(list.count);for(int i=0;i<10;i++){new Thread("t"+i){public void run(){for(int j=0;j<1000;j++){list.count++;}}}.start();}System.out.println(list.count);}}

  

如果想確保線程安全,那么必須使用synchronized鎖

synchronized (list) {list.count++;}

 

因為10個線程訪問的是同一個實例,所以使用對象鎖就可以了。

轉載于:https://www.cnblogs.com/warrior4236/p/7531973.html

總結

以上是生活随笔為你收集整理的并发编程基础之volatile关键字的用法的全部內容,希望文章能夠幫你解決所遇到的問題。

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