欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

深入淺析Java中的共享對象和存儲模型

本篇文章為大家展示了深入淺析Java中的共享對象和存儲模型,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

在郊區(qū)等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供網(wǎng)站建設、成都網(wǎng)站設計 網(wǎng)站設計制作按需網(wǎng)站策劃,公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,成都品牌網(wǎng)站建設,營銷型網(wǎng)站,外貿營銷網(wǎng)站建設,郊區(qū)網(wǎng)站建設費用合理。

Java 存儲模型和共享對象詳解

很多程序員對一個共享變量初始化要注意可見性和安全發(fā)布(安全地構建一個對象,并其他線程能正確訪問)等問題不是很理解,認為Java是一個屏蔽內存細節(jié)的平臺,連對象回收都不需要關心,因此談到可見性和安全發(fā)布大多不知所云。其實關鍵在于對Java存儲模型,可見性和安全發(fā)布的問題是起源于Java的存儲結構。

Java存儲模型原理

有很多書和文章都講解過Java存儲模型,其中一個圖很清晰地說明了其存儲結構:

深入淺析Java中的共享對象和存儲模型

由上圖可知, jvm系統(tǒng)中存在一個主內存(Main Memory或Java Heap Memory),Java中所有變量都儲存在主存中,對于所有線程都是共享的。 每條線程都有自己的工作內存(Working Memory),工作內存中保存的是主存中某些變量的拷貝,線程對所有變量的操作都是在工作內存中進行,線程之間無法相互直接訪問,變量傳遞均需要通過主存完成。

這個存儲模型很像我們常用的緩存與數(shù)據(jù)庫的關系,因此由此可以推斷JVM如此設計應該是為了提升性能,提高多線程的并發(fā)能力,并減少線程之間的影響。

Java存儲模型潛在的問題

一談到緩存, 我們立馬想到會有緩存不一致性問題,就是說當有緩存與數(shù)據(jù)庫不一致的時候,就需要有相應的機制去同步數(shù)據(jù)。同理,Java存儲模型也有這個問題,當一個線程在自己工作內存里初始化一個變量,當還沒來得及同步到主存里時,如果有其他線程來訪問它,就會出現(xiàn)不可預知的問題。另外,JVM在底層設計上,對與那些沒有同步到主存里的變量,可能會以不一樣的操作順序來執(zhí)行指令,舉個實際的例子:

public class PossibleReordering { 
  static int x = 0, y = 0; 
  static int a = 0, b = 0; 
  public static void main(String[] args) 
      throws InterruptedException { 
    Thread one = new Thread(new Runnable() { 
      public void run() { 
        a = 1; 
        x = b; 
      } 
    }); 
    Thread other = new Thread(new Runnable() { 
      public void run() { 
        b = 1; 
        y = a; 
      } 
    }); 
    one.start(); other.start(); 
    one.join();  other.join(); 
    System.out.println("( "+ x + "," + y + ")"); 
  } 
} 

由于,變量x,y,a,b沒有安全發(fā)布,導致會不以規(guī)定的操作順序來執(zhí)行這次四次賦值操作,有可能出現(xiàn)以下順序:

深入淺析Java中的共享對象和存儲模型

出現(xiàn)這個問題也可以理解,因為既然這些對象不可見,也就是說本應該隔離在各個線程的工作區(qū)內,那么對于有些無關順序的指令,打亂順序執(zhí)行在JVM看來也是可行的。

因此,總結起來,會有以下兩種潛在問題:

  1. 緩存不一致性
  2. 重排序執(zhí)行
     

解決Java存儲模型潛在的問題

為了能讓開發(fā)人員安全正確地在Java存儲模型上編程,JVM提供了一個happens-before原則,有人整理得非常好,我摘抄如下:

  1. 在程序順序中, 線程中的每一個操作, 發(fā)生在當前操作后面將要出現(xiàn)的每一個操作之前.
  2. 對象監(jiān)視器的解鎖發(fā)生在等待獲取對象鎖的線程之前.
  3. 對volitile關鍵字修飾的變量寫入操作, 發(fā)生在對該變量的讀取之前.
  4. 對一個線程的 Thread.start() 調用 發(fā)生在啟動的線程中的所有操作之前.
  5. 線程中的所有操作 發(fā)生在從這個線程的 Thread.join()成功返回的所有其他線程之前.
     

有了原則還不夠,Java提供了以下工具和方法來保證變量的可見性和安全發(fā)布:

  1. 使用 synchronized來同步變量初始化。此方式會立馬把工作內存中的變量同步到主內存中
  2. 使用 volatile關鍵字來標示變量。此方式會直接把變量存在主存中而不是工作內存中
  3. final變量。常量內也是存于主存中
     

另外,一定要明確只有共享變量才會有以上那些問題,如果變量只是這個線程自己使用,就不用擔心那么多問題了
搞清楚Java存儲模型后,再來看共享對象可見性和安全發(fā)布的問題就較為容易了

共享對象的可見性

當對象在從工作內存同步到主內存之前,那么它就是不可見的。若有其他線程在存取不可見對象就會引發(fā)可見性問題,看下面一個例子:

public class NoVisibility { 
  private static boolean ready; 
  private static int number; 
  private static class ReaderThread extends Thread { 
    public void run() { 
      while (!ready) 
        Thread.yield(); 
      System.out.println(number); 
    } 
  } 
  public static void main(String[] args) { 
    new ReaderThread().start(); 
    number = 42; 
    ready = true; 
  } 
} 

按照正常邏輯,應該會輸出42,但其實際結果會非常奇怪,可能會永遠沒有輸出(因為ready為false),可能會輸出0(因為重排序問題導致ready=true先執(zhí)行)。再舉一個更為常見的例子,大家都喜歡用只有set和get方法的pojo來設計領域模型,如下所示:

@NotThreadSafe 
public class MutableInteger { 
  private int value; 
  public int get() { return value; } 
  public void set(int value) { this.value = value; } 
} 

但是,當有多個線程同時來存取某一個對象時,可能就會有類似的可見性問題。
為了保證變量的可見性,一般可以用鎖、 synchronized關鍵字、 volatile關鍵字或直接設置為final

共享變量發(fā)布

共享變量發(fā)布和我們常說的發(fā)布程序類似,就是說讓本屬于內部的一個變量變?yōu)橐粋€可以被外部訪問的變量。發(fā)布方式分為以下幾種:

  • 將對象引用存儲到公共靜態(tài)域
  • 初始化一個可以被外部訪問的對象
  • 將對象引用存儲到一個集合里

安全發(fā)布和保證可見性的方法類似,就是要同步發(fā)布動作,并使發(fā)布后的對象可見。

線程安全

其實當我們把這些變量封閉在本線程內訪問,就可以從根本上避免以上問題,現(xiàn)實中存在很多例子通過線程封閉來安全使用本不是線程安全的對象,比如:

  1. swing的可視化組件和數(shù)據(jù)模型對象并不是線程安全的,它通過將它們限制到swing的事件分發(fā)線程中,實現(xiàn)線程安全
  2. JDBC Connection對象沒有要求為線程安全,但JDBC的存取模式?jīng)Q定了一個Connection只會同時被一個線程使用
  3. ThreadLocal把變量限制在本線程中共享

上述內容就是深入淺析Java中的共享對象和存儲模型,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站名稱:深入淺析Java中的共享對象和存儲模型
文章URL:http://chinadenli.net/article10/jgjdgo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供電子商務、小程序開發(fā)外貿建站、App開發(fā)、網(wǎng)站內鏈、動態(tài)網(wǎng)站

廣告

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

微信小程序開發(fā)
亚洲在线观看福利视频| 国产又长又粗又爽免费视频| 色狠狠一区二区三区香蕉蜜桃| 久久热在线免费视频精品| 欧洲偷拍视频中文字幕| 亚洲国产另类久久精品| 欧美一区二区日韩一区二区| 91在线播放在线播放观看| 在线观看视频成人午夜| 欧美二区视频在线观看| 色婷婷国产精品视频一区二区保健| 欧美整片精品日韩综合| 国产传媒中文字幕东京热| 国产亚洲精品久久99| 乱女午夜精品一区二区三区| 国产精品熟女在线视频| 两性色午夜天堂免费视频| 亚洲欧美黑人一区二区| 欧美精品一区二区三区白虎| 精品久久av一二三区| 精品一区二区三区人妻视频| 国产精品日韩欧美一区二区| 尹人大香蕉一级片免费看| 青青操成人免费在线视频| 精品熟女少妇av免费久久野外| 精品一区二区三区三级视频| 午夜福利激情性生活免费视频| 日韩欧美第一页在线观看| 91熟女大屁股偷偷对白| 日本精品最新字幕视频播放| 老鸭窝老鸭窝一区二区| 午夜激情视频一区二区| 国产一区二区不卡在线视频| 99久只有精品免费视频播放| 91人人妻人人爽人人狠狠| 日本精品啪啪一区二区三区| 久久99精品国产麻豆婷婷洗澡| 国产精品免费不卡视频| 国产精品九九九一区二区 | 日韩av生活片一区二区三区| 国产情侣激情在线对白|