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

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

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

    隨筆-179  評論-666  文章-29  trackbacks-0

    今天我在思考有關(guān)線程同步的問題,于是找到了這么一篇東西,放這里存一下。


    例圖

    圖例說明:左邊帶麻點的是synchronized方法或代碼塊。右邊的是普通方法。黃色的是該對象(也稱之為實例)的key,每個對象有且只有一個key。只有擁有該key的線程才能進入synchronized方法。

    打個比方:一個object就像一個大房子,大門永遠打開。房子里有很多房間(也就是方法)。這些房間有上鎖的(synchronized方法),和不上鎖之分(普通方法)。房門口放著一把鑰匙(key),這把鑰匙可以打開所有上鎖的房間。另外我把所有想調(diào)用該對象方法的線程比喻成想進入這房子某個房間的人。所有的東西就這么多了,下面我們看看這些東西之間如何作用的。

    在此我們先來明確一下我們的前提條件。該對象至少有一個synchronized方法,否則這個key還有啥意義。當(dāng)然也就不會有我們的這個主題了。

    一個人想進入某間上了鎖的房間,他來到房子門口,看見鑰匙在那兒(說明暫時還沒有其他人要使用上鎖的房間)。于是他走上去拿到了鑰匙,并且按照自己的計劃使用那些房間。注意一點,他每次使用完一次上鎖的房間后會馬上把鑰匙還回去。即使他要連續(xù)使用兩間上鎖的房間,中間他也要把鑰匙還回去,再取回來。

    因此,普通情況下鑰匙的使用原則是:“隨用隨借,用完即還。”

    這時其他人可以不受限制的使用那些不上鎖的房間,一個人用一間可以,兩個人用一間也可以,沒限制。但是如果當(dāng)某個人想要進入上鎖的房間,他就要跑到大門口去看看了。有鑰匙當(dāng)然拿了就走,沒有的話,就只能等了。

    要是很多人在等這把鑰匙,等鑰匙還回來以后,誰會優(yōu)先得到鑰匙?Not guaranteed。象前面例子里那個想連續(xù)使用兩個上鎖房間的家伙,他中間還鑰匙的時候如果還有其他人在等鑰匙,那么沒有任何保證這家伙能再次拿到。(JAVA規(guī)范在很多地方都明確說明不保證,象Thread.sleep()休息后多久會返回運行,相同優(yōu)先權(quán)的線程那個首先被執(zhí)行,當(dāng)要訪問對象的鎖被釋放后處于等待池的多個線程哪個會優(yōu)先得到,等等。我想最終的決定權(quán)是在JVM,之所以不保證,就是因為JVM在做出上述決定的時候,絕不是簡簡單單根據(jù)一個條件來做出判斷,而是根據(jù)很多條。而由于判斷條件太多,如果說出來可能會影響JAVA的推廣,也可能是因為知識產(chǎn)權(quán)保護的原因吧。SUN給了個不保證就混過去了。無可厚非。但我相信這些不確定,并非完全不確定。因為計算機這東西本身就是按指令運行的。即使看起來很隨機的現(xiàn)象,其實都是有規(guī)律可尋。學(xué)過計算機的都知道,計算機里隨機數(shù)的學(xué)名是偽隨機數(shù),是人運用一定的方法寫出來的,看上去隨機罷了。另外,或許是因為要想弄的確定太費事,也沒多大意義,所以不確定就不確定了吧。)

    再來看看同步代碼塊。和同步方法有小小的不同。

    1.從尺寸上講,同步代碼塊比同步方法小。你可以把同步代碼塊看成是沒上鎖房間里的一塊用帶鎖的屏風(fēng)隔開的空間。

    2.同步代碼塊還可以人為的指定獲得某個其它對象的key。就像是指定用哪一把鑰匙才能開這個屏風(fēng)的鎖,你可以用本房的鑰匙;你也可以指定用另一個房子的鑰匙才能開,這樣的話,你要跑到另一棟房子那兒把那個鑰匙拿來,并用那個房子的鑰匙來打開這個房子的帶鎖的屏風(fēng)。

    記住你獲得的那另一棟房子的鑰匙,并不影響其他人進入那棟房子沒有鎖的房間。

    為什么要使用同步代碼塊呢?我想應(yīng)該是這樣的:首先對程序來講同步的部分很影響運行效率,而一個方法通常是先創(chuàng)建一些局部變量,再對這些變量做一些操作,如運算,顯示等等;而同步所覆蓋的代碼越多,對效率的影響就越嚴(yán)重。因此我們通常盡量縮小其影響范圍。如何做?同步代碼塊。我們只把一個方法中該同步的地方同步,比如運算。

    另外,同步代碼塊可以指定鑰匙這一特點有個額外的好處,是可以在一定時期內(nèi)霸占某個對象的key。還記得前面說過普通情況下鑰匙的使用原則嗎。現(xiàn)在不是普通情況了。你所取得的那把鑰匙不是永遠不還,而是在退出同步代碼塊時才還。

    還用前面那個想連續(xù)用兩個上鎖房間的家伙打比方。怎樣才能在用完一間以后,繼續(xù)使用另一間呢。用同步代碼塊吧。先創(chuàng)建另外一個線程,做一個同步代碼塊,把那個代碼塊的鎖指向這個房子的鑰匙。然后啟動那個線程。只要你能在進入那個代碼塊時抓到這房子的鑰匙,你就可以一直保留到退出那個代碼塊。也就是說你甚至可以對本房內(nèi)所有上鎖的房間遍歷,甚至再sleep(10*60*1000),而房門口卻還有1000個線程在等這把鑰匙呢。很過癮吧。

    在此對sleep()方法和鑰匙的關(guān)聯(lián)性講一下。一個線程在拿到key后,且沒有完成同步的內(nèi)容時,如果被強制sleep()了,那key還一直在它那兒。直到它再次運行,做完所有同步內(nèi)容,才會歸還key。記住,那家伙只是干活干累了,去休息一下,他并沒干完他要干的事。為了避免別人進入那個房間把里面搞的一團糟,即使在睡覺的時候他也要把那唯一的鑰匙戴在身上。

    最后,也許有人會問,為什么要一把鑰匙通開,而不是一個鑰匙一個門呢?我想這純粹是因為復(fù)雜性問題。一個鑰匙一個門當(dāng)然更安全,但是會牽扯好多問題。鑰匙的產(chǎn)生,保管,獲得,歸還等等。其復(fù)雜性有可能隨同步方法的增加呈幾何級數(shù)增加,嚴(yán)重影響效率。

    這也算是一個權(quán)衡的問題吧。為了增加一點點安全性,導(dǎo)致效率大大降低,是多么不可取啊。

    摘自:http://www.54bk.com/more.asp?name=czp&id=2097

    posted on 2005-11-07 14:33 Alpha 閱讀(6048) 評論(5)  編輯  收藏

    評論:
    # re: 同步synchronized方法和代碼塊 2006-11-18 16:15 | 124
    講的很好,很形象,也很詳細  回復(fù)  更多評論
      
    # re: 同步synchronized方法和代碼塊 2006-11-29 16:10 | 拉拉
    不錯不錯~~  回復(fù)  更多評論
      
    # re: 同步synchronized方法和代碼塊 2006-12-28 19:56 | rr
    要是有例子就更好了  回復(fù)  更多評論
      
    # re: 同步synchronized方法和代碼塊[未登錄] 2007-04-19 11:27 | karin
    附加例子會更清楚!  回復(fù)  更多評論
      
    # re: 同步synchronized方法和代碼塊 2008-01-09 09:57 | walker
    搞什么啊?圖片沒有顯示!!!!  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲网红精品大秀在线观看| 99re在线精品视频免费| 亚洲人精品亚洲人成在线| 中文字幕精品三区无码亚洲| 久久受www免费人成_看片中文| 毛片A级毛片免费播放| 国产一级淫片免费播放| 中文字幕亚洲无线码a| 亚洲精品第五页中文字幕| 99xxoo视频在线永久免费观看| 亚洲国产高清在线| 亚洲第一se情网站| jizz免费观看视频| 免费专区丝袜脚调教视频| 免费v片在线观看品善网| 亚洲毛片一级带毛片基地| 67pao强力打造高清免费| 亚洲欧洲中文日韩久久AV乱码| 亚洲日产2021三区| 黄床大片免费30分钟国产精品| 人禽杂交18禁网站免费| 亚洲国产精品久久久久婷婷老年 | 亚洲国产精品成人一区| 亚洲毛片无码专区亚洲乱| 国产精品免费观看久久| 国产亚洲欧美在线观看| 激情97综合亚洲色婷婷五| 在线日本高清免费不卡| 亚洲日韩激情无码一区| 久久精品国产亚洲av品善| 精品亚洲一区二区三区在线观看 | 亚洲免费一区二区| 成人爽a毛片免费| 亚洲黄黄黄网站在线观看| 亚洲成人免费在线| 中文字幕亚洲图片| 97在线观看永久免费视频| 337p日本欧洲亚洲大胆艺术| 四虎成人免费网站在线| 久久久久久亚洲精品影院| 亚洲午夜av影院|