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

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

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

    和風細雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術自出。

    線程的協調

    本文內容

    Java進行線程調度的方法.
    如何讓線程進入等待.
    wait set概念的理解.
    如何激活等待狀態的線程.

    進行線程協調的方法

    從上一章《線程的互斥》中我們知道,當方法體或代碼塊被synchronized方法修飾時,有一個線程在執行這部分代碼時,其它線程無法同時執行這部分代碼。但如果我們想進行更高效的處理如主動調整線程而不是讓線程被動等待和盲目競爭時該怎么處理呢?
    在Java中,有三個方法可以對線程進行主動高效的控制,它們是wait,notify和notifyAll。
    wait是主動讓線程等待的方法,而notify和notifyAll則是激活等待中的線程的方法。他們都是Object類的方法,也就是說任何對象都可以使用這三個方法。

    Wait Set-線程的休息室

    在學習使用wait,notify和notifyAll這三個方法之前,我們可以先理解一下Wait Set的概念,它是一個在某實例執行wait方法時,停止操作的線程的集合,類似于線程的休息室,每個實例都擁有這樣一個休息室。
    Wait方法是用來把線程請入這個休息室的,而notify和notifyAll這兩個方法是用來將進入休息室休息的線程激活的。
    wait Set是一個虛擬的概念,它既不是實例的字段,也不是可以獲取在實例上wait中線程的列表的方法.它只是用來幫助我們理解線程的等待和激活的。

    Wait方法,將線程放入Wait Set

    使用Wait方法時,線程即進入Wait set。如線程在執行代碼時遇到這樣的語句:xxObj.wait();則目前的線程會暫時停止運行,進入實例xxObj的wait Set.
    當線程進入Wait Set時,即釋放了對該實例的鎖定.也就是說,即使是被synchronized修飾的方法和代碼塊,當第一個線程進入實例的wait Set等待后,其它線程就可以再進入這部分代碼了.
    wait()前如果不寫某對象表示其前面的對象是this, wait()=this.wait();

    notify方法-從wait set中激活一個線程

    使用notify方法時,程序會從處于等待的實例的休息室中激活一個線程.代碼如下:
    xxObj.notify();程序將從xxObj的wait set中挑出一個激活.這個線程即準備退出wait set.當當前線程釋放對xxObj的鎖定后,這個線程即獲取這個鎖定,從上次的停止點-執行wait的地方開始運行。
    線程必須有調用的實例的鎖定,才能執行notify方法.
    Wait set中處于等待狀態的線程有多個,具體激活那一個依環境和系統而變,事先無法辯明.我們大致可理解為隨機挑選了一個.

    notifyAll方法-激活wait set中所有等待的線程

    當執行notifyAll方法時,實例中所有處于等待狀態的線程都會被激活.代碼為:
    xxObj.notifyAll();執行此代碼后xxObj的wait set中所有處于等待中的線程都會被激活.但具體那個線程獲取執行wait方法時釋放的鎖定要靠競爭,最終只能有一個線程獲得鎖定,其它的線程只能繼續回去等待.
    notifyAll與notify的差異在于notifyAll激活所有wait set中等待的線程,而notify只激活其中的一個.

    該使用notify還是notifyAll

    建議:
    1) 選擇notifyAll比notify穩當安全,如果notify處理得不好,程序會有隱患.
    2) 選擇notifyAll比notify可靠,是大多數程序的首選.
    3) 當你對代碼已經很清楚,對線程理解也很透徹時,你可以選擇使用notify,發揮其處理速度高的優勢.

    當前線程必須持有欲調用實例的鎖定,才能調用wait,notify和notifyAll這三個方法.

    如果代碼是xxObj.notifyAll(或wait, notify)(),則這行代碼必須處于synchronized(xxObj){…}代碼塊中.
    如果代碼是this.notifyAll(或wait, notify)(),則這行代碼必須處于synchronized修飾的方法中.
    前面說過, notifyAll和notify會激活線程去獲得進入wait時釋放的鎖定,但這個鎖定要等剛才執行notifyAll或notify方法的線程釋放這個鎖定才能獲取.

    總結

    1) wait,notify和notifyAll都是java.lang.Object的方法,它們用來對線程進行調度.
    2) obj.wait()是把執行這句的線程放入obj的wait set中.
    3) obj.notify()是從wait set中喚醒一個線程,這個線程在當前線程釋放對obj的鎖定后即獲取這個鎖定.
    4) obj.notifyAll()是喚醒所有在obj的wait set中的線程,這批線程在當前線程釋放obj的鎖定后去競爭這個鎖定,最終只有一個能獲得,其它的又重新返回wait set等待下一次激活.
    5) 執行這個wait,notify和notifyAll這三個方法前,當前線程(即執行obj.wait(), obj.notify()和obj.notifyAll()代碼的線程)必須持有obj的鎖定.

    posted on 2008-02-22 14:13 和風細雨 閱讀(324) 評論(0)  編輯  收藏 所屬分類: 線程

    主站蜘蛛池模板: 国产A∨免费精品视频| 亚洲欧洲无码AV不卡在线| 久久久精品2019免费观看| 久久久久亚洲AV成人网人人软件| 国产成人精品亚洲精品| 78成人精品电影在线播放日韩精品电影一区亚洲 | 亚洲av永久综合在线观看尤物| 免费A级毛片在线播放| 国产亚洲3p无码一区二区| 成全视频高清免费观看电视剧| 亚洲无av在线中文字幕| 亚洲综合一区无码精品| 国内大片在线免费看| 亚洲AV无码男人的天堂| heyzo亚洲精品日韩| 在线成人精品国产区免费| 亚洲成AV人在线播放无码| 亚洲区日韩精品中文字幕| 青青草国产免费久久久下载 | 亚洲一区二区三区夜色| 亚洲色大网站WWW永久网站| 最近高清国语中文在线观看免费| 日韩亚洲一区二区三区| 久久永久免费人妻精品下载| 亚洲日本国产精华液| 高清国语自产拍免费视频国产| 国产成人va亚洲电影| 亚洲精品无码Av人在线观看国产| 国产精品免费看久久久| 亚洲午夜在线播放| 免费A级毛片无码久久版| 亚洲熟妇久久精品| 亚洲高清免费视频| 在线观看亚洲AV日韩AV| 伊人久久亚洲综合影院| 免费国产99久久久香蕉| 亚洲日韩中文字幕一区| 亚洲精品色婷婷在线影院| 成人片黄网站色大片免费观看APP| 亚洲AV一二三区成人影片| 亚洲第一区精品日韩在线播放|