内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

如何實(shí)現(xiàn)Java并發(fā)volatile可見性

小編這次要給大家分享的是如何實(shí)現(xiàn)Java并發(fā)volatile可見性,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

為望江等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及望江網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、望江網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

普通讀 無法及時(shí)獲得 主內(nèi)存變量

public class volatileTest {
  static boolean flag = false;//非volatile變量

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

主線程已經(jīng)修改了flag為true,但子線程一直不會(huì)退出循環(huán),因?yàn)樽泳€程一直沒有同步到 主內(nèi)存中的變量的值。

如何實(shí)現(xiàn)Java并發(fā)volatile可見性

截圖可見程序一直沒有退出,使用dump threads后:

"Thread-0" #12 prio=5 os_prio=0 tid=0x0000000022d89800 nid=0x168 runnable [0x00000000248df000]
java.lang.Thread.State: RUNNABLE
at volatileTest$1.run(volatileTest.java:10)
at java.lang.Thread.run(Thread.java:745)

volatile讀 及時(shí)獲得 主內(nèi)存變量

public class volatileTest {
  static volatile boolean flag = false;//volatile變量

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

加了一個(gè)volatile關(guān)鍵字,子線程就能檢測到flag的變化了。子線程會(huì)退出。

普通讀+sleep

public class volatileTest {
  static boolean flag = false;//非volatile變量

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
          try {
            Thread.sleep(1);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

加了sleep,子線程會(huì)退出。

其實(shí)就算變量不是volatile的,JVM也會(huì)盡量去保證可見性。最開始的例子,由于CPU一直執(zhí)行循環(huán),沒有其他時(shí)間來獲取 主內(nèi)存中的變量的最新值,但加了sleep后,CPU就有時(shí)間去獲取 主內(nèi)存中的東西了。

普通讀+同步塊

public class volatileTest {
  static boolean flag = false;//非volatile變量
  static Object sync = new Object();

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
          synchronized (sync) {}//隨便synchronized一個(gè)對象
          //synchronized (this)也可以
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

加了同步塊,子線程會(huì)退出。

這是因?yàn)閟ynchronized具體過程是:

  • 獲得同步鎖;
  • 清空工作內(nèi)存;
  • 從主內(nèi)存拷貝對象副本到工作內(nèi)存;
  • 執(zhí)行代碼(計(jì)算或者輸出等);
  • 刷新主內(nèi)存數(shù)據(jù);
  • 釋放同步鎖。

簡單的說,synchronized進(jìn)入時(shí),會(huì)將 主內(nèi)存中最新的變量,拷貝進(jìn) 自己線程 的工作內(nèi)存。synchronized退出時(shí),會(huì)把 自己線程的工作內(nèi)存的變量 弄進(jìn) 主內(nèi)存中。

同步塊 遭遇 鎖消除

public class volatileTest {
  static boolean flag = false;//非volatile變量

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
          synchronized (new Object()){}
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

子線程不會(huì)退出。

原因是:synchronized (new Object()){}中這個(gè)Object永遠(yuǎn)不可能逃逸到同步塊以外去,所以同步操作其實(shí)根本不需要執(zhí)行了,既然沒有執(zhí)行同步,那么相當(dāng)于這里是啥也沒有。

普通讀+System.out.println

public class volatileTest {
  static boolean flag = false;

  public static void main(String[] args) throws Exception {
    new Thread(new Runnable() {
      @Override
      public void run() {
        while(!flag){
          System.out.println("子線程running");
        };
      }
    }).start();
    Thread.sleep(100);
    flag = true;
    System.out.println("主線程運(yùn)行完畢");
  }
}

加了System.out.println,子線程會(huì)退出。

因?yàn)閛ut這個(gè)PrintStream實(shí)例的println實(shí)現(xiàn)是:

  public void println(String x) {
    synchronized (this) {
      print(x);
      newLine();
    }
  }

因?yàn)樗灿型綁K。

看完這篇關(guān)于如何實(shí)現(xiàn)Java并發(fā)volatile可見性的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。

網(wǎng)頁名稱:如何實(shí)現(xiàn)Java并發(fā)volatile可見性
當(dāng)前URL:http://www.rwnh.cn/article26/jcgjcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、ChatGPT、做網(wǎng)站、虛擬主機(jī)、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
米易县| 清丰县| 咸宁市| 邯郸县| 吴堡县| 松潘县| 乌兰县| 甘谷县| 淳化县| 河南省| 明水县| 宁国市| 宁乡县| 泸西县| 兰州市| 古交市| 得荣县| 乡城县| 河间市| 宜丰县| 上杭县| 永定县| 鹤峰县| 禹州市| 房山区| 宝丰县| 定结县| 阳泉市| 上思县| 麦盖提县| 万盛区| 郸城县| 湟中县| 安平县| 塘沽区| 灵山县| 民勤县| 灯塔市| 广宁县| 东源县| 准格尔旗|