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

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

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

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    synchronized 和 volatile

    Posted on 2010-01-14 14:36 瘋狂 閱讀(1098) 評論(0)  編輯  收藏 所屬分類: java
     

    為了確??梢栽诰€程之間以受控方式共享數(shù)據(jù),Java 語言提供了兩個關(guān)鍵字:synchronizedvolatile。

    Synchronized 有兩個重要含義:它確保了一次只有一個線程可以執(zhí)行代碼的受保護(hù)部分(互斥,mutual exclusion 或者說 mutex),而且它確保了一個線程更改的數(shù)據(jù)對于其它線程是可見的(更改的可見性)。

    如果沒有同步,數(shù)據(jù)很容易就處于不一致狀態(tài)。例如,如果一個線程正在更新兩個相關(guān)值(比如,粒子的位置和速率),而另一個線程正在讀取這兩個值,有可能在第一個線程只寫了一個值,還沒有寫另一個值的時候,調(diào)度第二個線程運(yùn)行,這樣它就會看到一個舊值和一個新值。同步讓我們可以定義必須原子地運(yùn)行的代碼塊,這樣對于其他線程而言,它們要么都執(zhí)行,要么都不執(zhí)行。

    同步的原子執(zhí)行或互斥方面類似于其它操作環(huán)境中的臨界段的概念。


    同步可以讓我們確保線程看到一致的內(nèi)存視圖。

    處理器可以使用高速緩存加速對內(nèi)存的訪問(或者編譯器可以將值存儲到寄存器中以便進(jìn)行更快的訪問)。在一些多處理器體系結(jié)構(gòu)上,如果在一個處理器的高速緩存中修改了內(nèi)存位置,沒有必要讓其它處理器看到這一修改,直到刷新了寫入器的高速緩存并且使讀取器的高速緩存無效。

    這表示在這樣的系統(tǒng)上,對于同一變量,在兩個不同處理器上執(zhí)行的兩個線程可能會看到兩個不同的值!這聽起來很嚇人,但它很常見。它只是表示在訪問其它線程使用或修改的數(shù)據(jù)時,必須遵循某些規(guī)則。

    Volatile 比同步更簡單,只適合于控制對基本變量(整數(shù)、布爾變量等)的單個實(shí)例的訪問。當(dāng)一個變量被聲明成 volatile,任何對該變量的寫操作都會繞過高速緩存,直接寫入主內(nèi)存,而任何對該變量的讀取也都繞過高速緩存,直接取自主內(nèi)存。這表示所有線程在任何時候看到的 volatile 變量值都相同。

    如果沒有正確的同步,線程可能會看到舊的變量值,或者引起其它形式的數(shù)據(jù)損壞。

     
    簡單的同步示例 第 6 頁(共12 頁)


    使用 synchronized 塊可以讓您將一組相關(guān)更新作為一個集合來執(zhí)行,而不必?fù)?dān)心其它線程中斷或看到計算的中間結(jié)果。以下示例代碼將打印“1 0”或“0 1”。如果沒有同步,它還會打印“1 1”(或“0 0”,隨便您信不信)。

    
    public class SyncExample {
    private static lockObject = new Object();
    private static class Thread1 extends Thread {
    public void run() {
    synchronized (lockObject) {
    x = y = 0;
    System.out.println(x);
    }
    }
    }
    private static class Thread2 extends Thread {
    public void run() {
    synchronized (lockObject) {
    x = y = 1;
    System.out.println(y);
    }
    }
    }
    public static void main(String[] args) {
    new Thread1().run();
    new Thread2().run();
    }
    }
    
    

    在這兩個線程中都必須使用同步,以便使這個程序正確工作。

    Volatile 對于確保每個線程看到最新的變量值非常有用,但有時我們需要保護(hù)比較大的代碼片段,如涉及更新多個變量的片段。

    同步使用監(jiān)控器(monitor)或鎖的概念,以協(xié)調(diào)對特定代碼塊的訪問。

    每個 Java 對象都有一個相關(guān)的鎖。同一時間只能有一個線程持有 Java 鎖。當(dāng)線程進(jìn)入 synchronized 代碼塊時,線程會阻塞并等待,直到鎖可用,當(dāng)它可用時,就會獲得這個鎖,然后執(zhí)行代碼塊。當(dāng)控制退出受保護(hù)的代碼塊時,即到達(dá)了代碼塊末尾或者拋出了沒有在 synchronized 塊中捕獲的異常時,它就會釋放該鎖。

    這樣,每次只有一個線程可以執(zhí)行受給定監(jiān)控器保護(hù)的代碼塊。從其它線程的角度看,該代碼塊可以看作是原子的,它要么全部執(zhí)行,要么根本不執(zhí)行。

    主站蜘蛛池模板: 亚洲入口无毒网址你懂的| 一级毛片aa高清免费观看| 国产精品免费小视频| 一级毛片a免费播放王色| 亚洲综合男人的天堂色婷婷| 成年女人色毛片免费看| 一级做a爰片性色毛片免费网站 | 四虎影视大全免费入口| 免费一级特黄特色大片| 亚洲成AV人片一区二区| 成人免费视频88| 国产精品网站在线观看免费传媒 | a级亚洲片精品久久久久久久| 最近中文字幕2019高清免费| 在线播放亚洲精品| 亚洲av无码精品网站| 永久免费av无码网站大全| 国产白丝无码免费视频| 色欲aⅴ亚洲情无码AV| 亚洲专区先锋影音| 亚洲精品成人在线| 成年女人毛片免费播放人| 精品国产免费一区二区三区香蕉 | 国产福利视精品永久免费| 国产区在线免费观看| 亚洲熟女乱色一区二区三区| 亚洲色成人中文字幕网站| 波多野结衣久久高清免费| 色欲A∨无码蜜臀AV免费播 | 亚洲精品视频在线观看视频| 亚洲精品黄色视频在线观看免费资源| 亚洲一级毛片免费在线观看| 成人A毛片免费观看网站| 久久亚洲中文字幕无码| 亚洲天堂一区在线| 亚洲va久久久噜噜噜久久狠狠| 亚洲av再在线观看 | 亚洲美女在线观看播放| 国产AV无码专区亚洲AWWW| 国产伦精品一区二区三区免费迷| 1000部拍拍拍18勿入免费视频软件 |