1. 程式人生 > >soa---java 多執行緒-執行緒記憶體模型

soa---java 多執行緒-執行緒記憶體模型

       現在soa 與分散式計算已經成為網際網路公司技術的標配

       那他包含的知識點應該熟悉瞭解,並以此為基礎,去應用,調優各種soa的框架。

       包含如下的四點,是分散式的基礎。

        a java 多執行緒 承接高吞吐量。

        b java nio 承接高併發,與互動協議的定製。

        c java 反射  完成序列化與反序列化。

        d 設計模式的應用 保證應用的擴充套件性。

         現在說說這java多執行緒

          對於現在的作業系統軟體與硬體,都有一個共同的目標,讓程式能夠並行的運算。而並行的基本單位是執行緒,因此我們應該瞭解執行緒。

          有如下幾個問題?先提出來.

  •           執行緒並行時,其jvm裡面是怎麼進行記憶體管理的?怎麼對共享變數是進行記憶體一致性的約束?
  •           執行緒之間怎麼進行協作?      
      對於第一個問題,java 裡面執行緒的記憶體模型這裡面簡單說一下       主要有堆記憶體,棧記憶體。        堆是各個執行緒進行共享的。而棧是執行緒獨有的。因此如果執行緒之間如果說是要共享資料,那隻能是放到堆裡面。        執行緒讀取共有堆資料之間是有相應的快取器的,因此如果並行的話,不進行同步的話,就會產生a執行緒生產的資料還沒有寫到       主堆記憶體裡面去就會被b執行緒將髒資料讀出來進行計算,那也就是a執行緒的結果不被b執行緒看見,現實生活中可以想想轉帳就瞭解了。
    可以看如下圖明白,程式怎麼執行:      

     更厲害的就是這個程式的順序,有可能被編譯器,以及cpu進行重現編排了,這樣做的目的就是為了速度快,效率高。但有些可以調順序,有些是不能調的,那怎麼辦。不能調的告訴jvm,cpu就得了。      那java裡面如何解決這個問題呢,那就是同步,同步是需要裡面硬體進行支援的,但這個可以說比較的深了,瞭解一下就成, 因為了解到這裡,你可以認為那些搞jvm的人只是想個辦法寫個c++的指令就能讓cpu在資料計算的時候,看是到快取器裡面拿,還是到資料匯流排裡面拿。      以上就是說jvm有這些功能,那我們程式設計師如果能用到這些功能?無非就是寫一些標示讓jvm裡面去讀,讀到了,它就會按照你的指示去同步就好。     這裡有幾個java特有的關鍵字做同步的標識。     1 synchronized      2 volatile     對於 synchronized 這個 大家應該比較的熟悉,這玩意加到方法或者是塊裡面     那為什麼這玩意一加上去就會有同步的效果呢。這裡又牽扯到監視器,或者鎖。     由於這個程式是人設計的,肯定有人的思想裡面,大家發揮想象哈。    監視器 就像建了一個房子 但每次只能讓一個執行緒去獲取。這個房間通常裡面放了一些資料,從執行緒從房子裡面進去,再從房子裡面出來,這個房子是防止其他執行緒進去的。
正在進入房子 --->正在進入監視器。---不一定獲得了鎖 但執行了方法體裡面前面一段程式碼ⓐ 完全進入房子 --->獲取監視器進行時。   (是競爭的時候?) 正在佔有監視器--->擁有監視器。 離開房間          ---->釋放監視器。 離開整個建築   ---->離開監視器。---- 已經釋放了鎖,但必須執行方法體裡面後一部分程式碼 這裡面靈活性做得好,進去的人想出來,可以通過兩種途徑,    1 裡面有間休息室,可以休息,但必須將特權證得交出來。休息好了,再申請特權證在進來幹活。    2 把事做完了,將特權證交出來。該幹嘛,就幹嘛去。    就如下面的圖一樣  
對於volatile 你可以看成是小型的synchronized    但功能很弱哈,只是對於基本資料型別用的多,複雜內型,複雜的操作都不行,這個可以去檢視一個資料,這玩意主要用來做標誌位。原理就是執行緒每次讀這個變數,寫這個變數,都是在堆記憶體裡面直接改的。所有A執行緒一改,B執行緒就能馬上看到。       複雜的類,就不行了,複雜的操作也不行,比如volatile++都不行,這個可以查查資料。 加上這兩個就不會讓程式髒讀,寫,也不會讓編輯器,以及cpu 隨意的改變順序了。 另外還有一個final 修飾的類屬性,類物件沒構造完成之前,中間狀態不會讓別的執行緒看見。這個也可以查查這方面的資料。synchronized   ,volatile,final保證了,程式碼在cpu上執行指令順序的規定

以上是對於java 裡面記憶體模型的一個大概瞭解,有如下幾個特性是需要了解的。
  •    現實業務的原子性。(模擬現實業務,得到預期結果)
  •    記憶體可見性。(對於公共變數。前一原子性的操作結果,必須讓後一操作看到)
  •    一致性。(程式設計師程式設計的順序與機器執行程式碼的順序不一樣,但設計保證了結果的一致性) 
那如何在一堆的thread進行協調呢,下面文章牽扯到了thread各個api.,以及對於api的應用場景描述。