<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java Happens-Before 原則

          共 2135字,需瀏覽 5分鐘

           ·

          2022-11-03 23:08


          Happens-Before原則核心就是表達(dá)在一些條件下,前面的操作對于后面的操作是可見的。它有六個條件,或者說是六條原則。

          一、線程中的順序性原則

          這個最容易理解,這個原則是指在同一個線程中,按照程序的順序,前面的操作Happens-Before后面的操作。也就說在同一個線程中,前面先修改的數(shù)據(jù),對于后面的操作是可見的。下面舉例說明:

          int a = 1;
          if(a == 1){
            
          }

          上面代碼中第一行對變量a進(jìn)行的修改Happens-Before第二行查詢a的操作,所以第二行a == 1為true。

          二、volatile變量原則

          這個原則是指在對于用volatile修飾的變量,它的寫操作Happens-Before后續(xù)對它的讀操作。這個原則就是說在一個線程中先對volatile變量進(jìn)行了修改后,在另一個線程中讀取該volatile變量能夠讀到新值(因?yàn)镃PU緩存的存在,可能在一個線程中修改了普通變量,另一個線程無法感知)。當(dāng)然如果在同一個線程中,就可以直接使用原則一了。

          volatile int a = 1;
           
          // 線程A
          a = 2;
           
          // 線程B
          if(a == 2){
            
          }

          上面代碼中,假設(shè)有兩個線程并發(fā)執(zhí)行,線程A先對a進(jìn)行賦值操作(第四行),然后線程B立刻讀取a(第七行),此時能夠保證讀取的a一定是2。

          三、傳遞性

          這個原則是指Happens-Before原則是可以傳遞的,指如果A Happens-Before B,且B Happens-Before C,那么A Happens-Before C。

          volatile boolean a = false;
          int b = 1;
           
          // 線程A
          b = 2;
          a = true;
           
          // 線程B
          if(a){
            System.out.println(b);
          }

          上面代碼中,線程A先對b進(jìn)行賦值,然后對a進(jìn)行賦值,然后線程B讀取a后,然后執(zhí)行打印b的值(根據(jù)原則二a一定為true),b的值一定為2。因?yàn)楦鶕?jù)原則一,對b賦值Happens-Before對a賦值,再根據(jù)原則二,對a的賦值Happens-Before對a的讀取,最后再根據(jù)原則三,對b的賦值Happens-Before對b的讀取的,所以b一定為2。

          四、管程中鎖的原則

          這個原則是指對同一個鎖的解鎖Happens-Before后續(xù)對這個鎖的加鎖。

          int a = 1;
           
          // 線程執(zhí)行
          synchronized (this){
            if(a == 1){
              a = 2;
            }
          }

          上面代碼中,線程A先對a進(jìn)行賦值,然后解鎖,線程B再加鎖后,此時讀到的a一定為2。

          五、線程start原則

          這條原則是關(guān)于線程啟動的。它是指主線程A啟動子線程B后,子線程B能夠看到主線程在啟動子線程B前的操作。也就是說如果線程A調(diào)用線程B的 start() 方法(即在線程A中啟動線程B),那么該start()操作 Happens-Before 于線程B中的任意操作。

          int a = 1;
          Thread B = new Thread(() -> {
            // 讀取a
          });
          a = 2; // 假設(shè)能修改
          B.start();

          上面代碼中,線程A先對a進(jìn)行賦值,然后再啟動線程B,所以線程B如果能夠讀取a的話(當(dāng)然int類型,java中是不允許的),那么a一定為2。

          六、線程join原則

          這條是關(guān)于線程等待的。它是指主線程A等待子線程B完成(主線程A通過調(diào)用子線程B的join()方法實(shí)現(xiàn)),當(dāng)子線程B完成后(主線程A中join()方法返回),主線程能夠看到子線程的操作。

          int a = 1;
          Thread B = new Thread(() -> {
            // 修改a
            a = 2;  // 假設(shè)能修改
          });
          B.start();
          B.join();
          // 讀取a

          上面代碼中,讀到的a一定為2。也就是說線程B中的操作對于B.join()后面的操作都是可見的。

          source: cnblogs.com/dwtfukgv/p/15631282.html

          記得點(diǎn)「」和「在看」↓

          愛你們

          瀏覽 48
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  第一页在线视频 | 狠狠干狠狠干狠狠干 | 亚洲精品操逼视频 | 一卡二卡三卡 | 高清无码在线免费 |