并發(fā)編程系列之變量可見性問題探究

      網(wǎng)友投稿 691 2025-04-01

      并發(fā)編程系列之變量可見性問題探究


      1、什么是并發(fā)中的變量可見性問題

      以例子的形式看看,定義一個(gè)變量,先用static修飾,在主線程修改之后,看看在新開的子線程里能被看到?

      public class Example { private static boolean flag = true; public void testss() { new Thread(new Runnable() { @Override public void run() { int i = 0; while (IfTest.flag) { i++; } System.out.println(i); } }).start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } IfTest.flag = false; System.out.println("設(shè)置flag"); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      執(zhí)行,控制臺(tái)打印:

      設(shè)置flag

      ps:主線程對flag變量進(jìn)行修改,子線程是不能看到的,所以里面一直在循環(huán),不能打印統(tǒng)計(jì)數(shù)據(jù)值。然后怎么才能讓并發(fā)線程看見?

      方式1:使用volatile關(guān)鍵字

      public class Example { private static volatile boolean flag = true; public void testss() { new Thread(new Runnable() { @Override public void run() { int i = 0; while (IfTest.flag) { i++; } System.out.println(i); } }).start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } IfTest.flag = false; System.out.println("設(shè)置flag"); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      控制臺(tái)打印:

      設(shè)置flag

      72071943

      方式2:使用synchronized同步鎖

      public class Example { private static boolean flag = true; public void testss() { new Thread(new Runnable() { @Override public void run() { int i = 0; while (IfTest.flag) { synchronized (this) { i++; } } System.out.println(i); } }).start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } IfTest.flag = false; System.out.println("設(shè)置flag"); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      控制臺(tái)打印:

      設(shè)置flag

      86726163

      2、什么是Java內(nèi)存模型

      解答這個(gè)問題,需要涉及到Java的內(nèi)存模型,如下所示,Java內(nèi)存模型及操作規(guī)范:

      共享變量都是放在主內(nèi)存中的

      每個(gè)線程都有自己的工作內(nèi)存,線程只可操作自己的工作內(nèi)存

      線程要操作共享變量,需要從主內(nèi)存中讀取到工作內(nèi)存,改變值之后要從工作內(nèi)存同步到主內(nèi)存

      Java內(nèi)存模型的同步交換協(xié)議,規(guī)定了8種原子操作

      原子操作:不可被中斷的一個(gè)或一系列操作

      lock(鎖定):將主內(nèi)存中的變量鎖定,為一個(gè)線程所獨(dú)占

      unlock(解鎖):將lock加的鎖解除,其他的線程有機(jī)會(huì)訪問此變量

      read(讀取):作用于主內(nèi)存變量,將主內(nèi)存中的變量值讀取到工作內(nèi)存

      load(加載):作用于工作內(nèi)存,將read讀取到的值保存到工作內(nèi)存中的變量副本

      use(使用):作用于工作內(nèi)存變量,將值傳遞給線程的代碼執(zhí)行引擎

      assign(賦值):作用于工作內(nèi)存變量,將執(zhí)行引擎處理返回的值重新賦值給變量副本

      store(存儲(chǔ)):作用于工作內(nèi)存變量,將變量副本的值傳送到主內(nèi)存中

      write(寫入):作用于主內(nèi)存變量,將store傳送過來的值寫入到主內(nèi)存的共享變量中

      Java內(nèi)存模型的同步交互協(xié)議,執(zhí)行上述8種原子操作時(shí)必須滿足如下規(guī)則

      不允許read和load,store和write操作之一單獨(dú)出現(xiàn)。即不允許加載或同步工作到一半。

      不允許一個(gè)線程丟棄它最近的assign操作,即變量在工作內(nèi)存中改變之后,必須將數(shù)據(jù)同步回主內(nèi)存

      不允許一個(gè)線程無原因地(無assign操作)將數(shù)據(jù)從工作內(nèi)存同步到主內(nèi)存中。

      一個(gè)新的變量可能在主內(nèi)存中誕生。

      一個(gè)變量在同一個(gè)時(shí)刻只允許一條線程對其進(jìn)行l(wèi)ock操作,但lock操作可以被同一條線程重復(fù)執(zhí)行多次,多次lock之后必須要執(zhí)行相同次數(shù)unlock操作,變量才會(huì)解鎖

      如果對一個(gè)對象進(jìn)行l(wèi)ock操作,那么會(huì)清空工作內(nèi)存變量中的值,在執(zhí)行引擎使用這個(gè)變量前,需要重新執(zhí)行l(wèi)oad或assign操作初始變量的值

      如果一個(gè)對象事先沒有被lock,就不允許對其進(jìn)行unlock操作,也不允許去unlock一個(gè)被其他線程鎖住的變量。

      對一個(gè)變量執(zhí)行unlock操作之前,必須將此變量同步回主內(nèi)存中(執(zhí)行store、write)

      Java內(nèi)存模型的同步協(xié)議,操作規(guī)范

      將一個(gè)變量從主內(nèi)存復(fù)制到工作內(nèi)存要順序執(zhí)行read、load操作;要將變量從工作內(nèi)存同步回主內(nèi)存要用store、write操作。只要求順序執(zhí)行,不一定是連續(xù)執(zhí)行

      圖引用網(wǎng)上資料:

      3、保證變量可見性的方法

      并發(fā)編程系列之變量可見性問題探究

      final變量

      synchronized

      volatile修飾

      4、Synchronized怎么做到可見性

      synchronized語義規(guī)范:

      進(jìn)入同步塊前,先清空工作內(nèi)存中的共享變量,從主內(nèi)存加載

      解鎖前,必須將修改的共享變量同步回主內(nèi)存

      synchronized是如何做到線程安全的?

      鎖機(jī)制保護(hù)共享資源,只有獲得鎖的線程才能操作共享資源

      synchronized語義規(guī)范保證了修改共享資源后,會(huì)同步回主內(nèi)存,就做到了線程安全

      5、volatile關(guān)鍵字解密

      volatile語義規(guī)范:

      使用volatile變量時(shí),必須重新從主內(nèi)存加載到工作內(nèi)存,并且read、load是連續(xù)的

      修改volatile變量后,必須馬上同步回主內(nèi)存,并且store、write是連續(xù)的

      volatile可以做到線程安全?

      不能,因?yàn)関olatile沒有鎖機(jī)制,線程是可以并發(fā)操作共享資源的

      volatile相對synchronized有什么優(yōu)點(diǎn)?

      使用volatile比synchronized簡單

      volatile性能比synchronized好

      volatile的使用場景?

      volatile只能修飾成員變量

      在多線程并發(fā)的場景才使用

      volatile支持并發(fā)編程三大特效?

      并發(fā)編程三大特效:原子性、有序性、可見性。

      可見性:volatile和synchronized關(guān)鍵字一樣,都可以保證可見性

      有序性:volatile可以保證有序性,避免指令編排的情況,依賴于操作系統(tǒng)的內(nèi)存屏障

      原子行 :volatile只能保證單個(gè)操作的原子性,不能保證一系列操作的原子性,不能保證線程安全,所以說volatile不能保證原則性

      Java 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:wps文字如何添加備注
      下一篇:如何從Excel中的范圍或工作表中刪除所有公式?
      相關(guān)文章
      亚洲国产精彩中文乱码AV| 中文字幕亚洲一区| 亚洲爆乳无码一区二区三区| 亚洲精品第一国产综合境外资源 | 国产亚洲精品看片在线观看| 亚洲国产精品人人做人人爽| av无码东京热亚洲男人的天堂| 亚洲av成人片在线观看| 亚洲国产av玩弄放荡人妇| 亚洲JIZZJIZZ妇女| 亚洲Aⅴ在线无码播放毛片一线天| 亚洲狠狠色丁香婷婷综合| 亚洲AV综合永久无码精品天堂| 亚洲youwu永久无码精品 | 亚洲AV无码精品色午夜果冻不卡 | 久久亚洲国产成人影院| 亚洲熟妇无码AV不卡在线播放 | 亚洲大成色www永久网站| 亚洲国产精品无码久久一线| 久久精品国产精品亚洲精品| 亚洲av无码一区二区三区不卡| 亚洲AV无码精品色午夜果冻不卡 | 亚洲äv永久无码精品天堂久久 | 亚洲中文字幕乱码一区| 亚洲GV天堂GV无码男同| 亚洲äv永久无码精品天堂久久 | 亚洲中文字幕久久精品无码VA| 亚洲国产综合在线| 久久亚洲AV无码精品色午夜麻豆 | 18禁亚洲深夜福利人口| 亚洲AⅤ永久无码精品AA| 亚洲av无码成人精品区| 亚洲性在线看高清h片| 亚洲午夜久久久影院伊人| 亚洲av无码成人黄网站在线观看 | 香蕉视频亚洲一级| 亚洲日韩中文在线精品第一| 亚洲欧洲无码AV电影在线观看| 亚洲午夜视频在线观看| 亚洲人成高清在线播放| 亚洲熟妇AV一区二区三区浪潮|