<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 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    synchronized 和 volatile

    Posted on 2010-01-14 14:36 瘋狂 閱讀(1097) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): java
     

    為了確保可以在線程之間以受控方式共享數(shù)據(jù),Java 語(yǔ)言提供了兩個(gè)關(guān)鍵字:synchronizedvolatile

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

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

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


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

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

    這表示在這樣的系統(tǒng)上,對(duì)于同一變量,在兩個(gè)不同處理器上執(zhí)行的兩個(gè)線程可能會(huì)看到兩個(gè)不同的值!這聽(tīng)起來(lái)很?chē)樔耍?em>卻很常見(jiàn)。它只是表示在訪問(wèn)其它線程使用或修改的數(shù)據(jù)時(shí),必須遵循某些規(guī)則。

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

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

     
    簡(jiǎn)單的同步示例 第 6 頁(yè)(共12 頁(yè))


    使用 synchronized 塊可以讓您將一組相關(guān)更新作為一個(gè)集合來(lái)執(zhí)行,而不必?fù)?dān)心其它線程中斷或看到計(jì)算的中間結(jié)果。以下示例代碼將打印“1 0”或“0 1”。如果沒(méi)有同步,它還會(huì)打印“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();
    }
    }
    
    

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

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

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

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

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

    主站蜘蛛池模板: 在线亚洲精品视频| 亚洲综合另类小说色区色噜噜| 女人裸身j部免费视频无遮挡| 噜噜噜亚洲色成人网站∨| 在线观看特色大片免费网站| 亚洲真人无码永久在线| 亚洲一区二区电影| 两性刺激生活片免费视频| 亚洲午夜理论片在线观看| 在线看片无码永久免费aⅴ| 91成人在线免费视频| jizz日本免费| 日韩亚洲人成网站| 亚洲国产精品高清久久久| 免费成人黄色大片| 男人j进入女人j内部免费网站| 免费大片av手机看片高清| 亚洲欧美日韩中文无线码| 亚洲精品国产va在线观看蜜芽| 成人免费无码大片A毛片抽搐 | 97国产在线公开免费观看| 97在线视频免费公开视频| 香港一级毛片免费看| 美女视频黄.免费网址| 午夜亚洲国产精品福利| 亚洲AV日韩AV一区二区三曲| 亚洲午夜无码久久久久小说| 亚洲人成免费网站| 亚洲综合久久一本伊伊区| 亚洲人成激情在线播放| 久久精品国产亚洲av麻豆蜜芽| 亚洲精品日韩专区silk| 免费成人午夜视频| www国产亚洲精品久久久日本| 99热在线免费播放| 久久午夜伦鲁片免费无码| 99久久99热精品免费观看国产| 在线看片免费人成视久网| 69视频在线观看免费| av大片在线无码免费| 久久久受www免费人成|