<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-200  評論-148  文章-15  trackbacks-0
    【IT168 技術文檔】線程同步:

      由于同一進程的多個線程共享同一片存儲空間,在帶來方便的同時,也帶來了訪問沖突這個嚴重的問題。Java語言提供了專門機制以解決這種沖突,有效避免了同一個數據對象被多個線程同時訪問。

      需要明確的幾個問題:

      1)synchronized關鍵字可以作為函數的修飾符,也可作為函數內的語句,也就是平時說的同步方法和同步語句塊。如果再細的分 類,synchronized可作用于instance變量、object reference(對象引用)、static函數和class literals(類名稱字面常量)身上。

      2)無論synchronized關鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數當作鎖――而且同步方法很可能還會被其他線程的對象訪問。

      3)每個對象只有一個鎖(lock)與之相關聯。

      4)實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。

      1、synchronized關鍵字的作用域有二種:

      1)是某個對象實例內,synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線 程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的 synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;

      2)是某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。

      synchronized 方法控制對類成員變量的訪問:每個類實例對應一把鎖,每個 synchronized 方法都必須獲得調用該方法的類實例的鎖方能執行,否則所屬線程阻塞,方法一旦執行,就獨占該鎖,直到從該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得 該鎖,重新進入可執行狀態。這種機制確保了同一時刻對于每一個類實例,其所有聲明為 synchronized 的成員函數中至多只有一個處于可執行狀態(因為至多只有一個能夠獲得該類實例對應的鎖),從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變 量的方法均被聲明為 synchronized)。

      在 Java 中,不光是類實例,每一個類也對應一把鎖,這樣我們也可將類的靜態成員函數聲明為 synchronized ,以控制其對類的靜態成員變量的訪問。

      synchronized 方法的缺陷:同步方法,這時synchronized鎖定的是哪個對象呢?它鎖定的是調用這個同步方法對象。也就是說,當一個對象 P1在不同的線程中執行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所產生的另一對象P2卻可以任意調用這個被加 了synchronized關鍵字的方法.同步方法實質是將synchronized作用于object reference。――那個拿到了P1對象鎖的線程,才可以調用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同 步機制的控制,造成數據混亂:(;若將一個大的方法聲明為synchronized 將會大大影響效率,典型地,若將線程類的方法 run() 聲明為 synchronized ,由于在線程的整個生命期內它一直在運行,因此將導致它對本類任何 synchronized 方法的調用都永遠不會成功。當然我們可以通過將訪問類成員變量的代碼放到專門的方法中,將其聲明為 synchronized ,并在主方法中調用來解決這一問題,但是 Java 為我們提供了更好的解決辦法,那就是 synchronized 塊。

      2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用于方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/*區塊*/},它的作用域是當前對象。

      這時鎖就是對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當有一個明確的對象作為鎖時,就可以這樣寫程序,但當沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創建一個特殊的instance變量(它得是一個對象)來充當鎖:

      class Foo implements Runnable
      {
      
    privatebyte[] lock=newbyte[0]; // 特殊的instance變量

      Public
    void methodA()
      {
      synchronized(
    lock) { //… }

      }
      
    //…..

      }

      注:零長度的byte數組對象創建起來將比任何對象都經濟――查看編譯后的字節碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

      3.將synchronized作用于static 函數,示例代碼如下:

    ?

      Class Foo
      {
      
    public synchronized staticvoid methodAAA() // 同步的static 函數

      {
      
    //….

      }
      
    publicvoid methodBBB()
      {
      synchronized(Foo.
    class) // class literal(類名稱字面常量)

      } }

    ?

      代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數產生的效果是一樣的,取得的鎖很特別,是當前調用這個方法的對象所屬的類(Class,而不再是由這個Class產生的某個具體對象了)。

      可以推斷:如果一個類中定義了一個synchronized的static函數A,也定義了一個synchronized 的instance函數B,那么這個類的同一對象Obj在多線程中分別訪問A和B兩個方法時,不會構成同步,因為它們的鎖都不一樣。B方法的鎖是Obj這 個對象,而B的鎖是Obj所屬的那個Class。

      對共享資源的同步訪問更加安全的技巧:

      1) 定義private 的instance變量+它的 get方法,而不要定義public/protected的instance變量。如果將變量定義為public,對象在外界可以繞過同步方法的控制而直 接取得它,并改動它。這也是JavaBean的標準實現方式之一。

      2)如果instance變量是一個對象,如數組或ArrayList什么的,那上述方法仍然不安全,因為當外界對象通過get方法拿到這個 instance對象的引用后,又將其指向另一個對象,那么這個private變量也就變了,豈不是很危險。這個時候就需要將get方法也加上 synchronized同步,并且,只返回這個private對象的clone()――這樣,調用端得到的就是對象副本的引用了。

      補充:

      synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中并不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法。

    posted on 2008-08-01 09:56 無聲 閱讀(643) 評論(0)  編輯  收藏 所屬分類: 職場生活
    主站蜘蛛池模板: 亚洲乱码一区二区三区国产精品| 亚洲高清无在码在线电影不卡| 国产精品亚洲玖玖玖在线观看| 中文字幕亚洲电影| 亚洲高清视频在线观看| 亚洲一区二区三区免费在线观看| 亚洲 欧洲 视频 伦小说| 深夜A级毛片视频免费| 中文字幕视频在线免费观看| 最近中文字幕免费完整| 在线观看免费a∨网站| 一区国严二区亚洲三区| 亚洲国产精品国自产拍AV| 亚洲午夜在线一区| 国产成人久久精品亚洲小说| 最新久久免费视频| 7723日本高清完整版免费| 全部免费a级毛片| 亚洲一区二区三区四区在线观看| 亚洲一区二区三区写真| 国产97视频人人做人人爱免费| 少妇太爽了在线观看免费视频 | 美女无遮挡免费视频网站| 精选影视免费在线 | 台湾一级毛片永久免费| 内射无码专区久久亚洲| 亚洲最新永久在线观看| 色偷偷亚洲第一综合网| 免费人成毛片动漫在线播放| 好男人看视频免费2019中文| 国产亚洲美女精品久久久| 2020国产精品亚洲综合网| 久久久WWW免费人成精品| 无码国产精品久久一区免费| 伊人久久大香线蕉亚洲| 亚洲日韩国产精品乱-久| 永久免费av无码网站yy| 国产精品色午夜免费视频| 久久亚洲中文字幕精品有坂深雪| 男男黄GAY片免费网站WWW| 69国产精品视频免费|