日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java snychronized_Java synchronized同步线程机制(三) | 学步园

發布時間:2024/4/20 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java snychronized_Java synchronized同步线程机制(三) | 学步园 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面講了那么理論知識和例子,現在講講故事,畢竟故事所體現的原理更容易理解。

打個比方:一個object就像一個大房子,大門永遠打開。房子里有 很多房間(也就是方法)。這些房間有上鎖的(synchronized方法), 和不上鎖之分(普通方法)。房門口放著一把鑰匙(key),這把鑰匙可以打開所有上鎖的房間。另外我把所有想調用該對象方法的線程比喻成想進入這房子某個 房間的人。所有的東西就這么多了,下面我們看看這些東西之間如何作用的。在此我們先來明確一下我們的前提條件。該對象至少有一個synchronized方法,否則這個key還有啥意義。當然也就不會有我們的這個主題了。

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

因此,普通情況下鑰匙的使用原則是:“隨用隨借,用完即還。”這時其他人可以不受限制的使用那些不上鎖的房間,一個人用一間可以,兩個人用一間也可以,沒限制。但是如果當某個人想要進入上鎖的房間,他就要跑到大門口去看看了。有鑰匙當然拿了就走,沒有的話,就只能等了。要是很多人在等這把鑰匙,等鑰匙還回來以后,誰會優先得到鑰匙?Not guaranteed。象前面例子里那個想連續使用兩個上鎖房間的家伙,他中間還鑰匙的時候如果還有其他人在等鑰匙,那么沒有任何保證這家伙能再次拿到。 (JAVA規范在很多地方都明確說明不保證,象Thread.sleep()休息后多久會返回運行,相同優先權的線程那個首先被執行,當要訪問對象的鎖被

釋放后處于等待池的多個線程哪個會優先得

到,等等。我想最終的決定權是在JVM,之所以不保證,就是因為JVM在做出上述決定的時候,絕不是簡簡單單根據 一個條件來做出判斷,而是根據很多條。而由于判斷條件太多,如果說出來可能會影響JAVA的推廣,也可能是因為知識產權保護的原因吧。SUN給了個不保證 就混過去了。無可厚非。但我相信這些不確定,并非完全不確定。因為計算機這東西本身就是按指令運行的。即使看起來很隨機的現象,其實都是有規律可尋。學過 計算機的都知道,計算機里隨機數的學名是偽隨機數,是人運用一定的方法寫出來的,看上去隨機罷了。另外,或許是因為要想弄的確定太費事,也沒多大意義,所

以不確定就不確定了吧。)再來看看同步代碼塊。和同步方法有小小的不同。

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

2.同步代碼塊還可以人為的指定獲得某個其它對象的key。就像是指定用哪一把鑰匙才能開這個屏風的鎖,你可以用本房的鑰匙;你也可以指定

用另一個房子的鑰匙才能開,這樣的話,你要跑到另一棟房子那兒把那個鑰匙拿來,并用那個房子的鑰匙來打開這個房子的帶鎖的屏風。記住你獲得的那另一棟房子的鑰匙,并不影響其他人進入那棟房子沒有鎖的房間。為什么要使用同步代碼塊呢?我想應該是這樣的:首先對程序來講同步的部分很影響運行效率,而一個方法通常是先創建一些局部變

量,再對這些變量做一些 操作,如運算,顯示等等;而同步所覆蓋的代碼越多,對效率的影響就越嚴重。因此我們通常盡量縮小其影響范圍。

如何做?同步代碼塊。我們只把一個方法中該同 步的地方同步,比如運算。

另外,同步代碼塊可以指定鑰匙這一特點有個額外的好處,是可以在一定時期內霸占某個對象的key。還記得前面說過普通情況下鑰匙的使用原則嗎。現在不是普通情況了。你所取得的那把鑰匙不是永遠不還,而是在退出同步代碼塊時才還。還用前面那個想連續用兩個上鎖房間的家伙打比方。怎樣才能在用完一間以后,繼續使用另一間呢。用同步代碼塊吧。先創建另外一個線程,做一個同步代碼 塊,把那個代碼塊的鎖指向這個房子的鑰匙。然后啟動那個線程。只要你能在進入那個代碼塊時抓到這房子的鑰匙

,你就可以一直保留到退出那個代碼塊。也就是說 你甚至可以對本房內所有上鎖的房間遍歷,甚至再sleep(10*60*1000),而房門口卻還有1000個線程在等這把鑰匙呢。很過癮吧。

在此對sleep()方法和鑰匙的關聯性講一下。一個線程在拿到key后,且沒有完成同步的內容時,如果被強制sleep()了,那key還一直在 它那兒。直到它再次運行,做完所有同步內容,才會歸還key。記住,那家伙只是干活干累了,去休息一下,他并沒干完他要干的事。為了避免別人進入那個房間 把里面搞的一團糟,即使在睡覺的時候他也要把那唯一的鑰匙戴在身上。最后,也許有人會問,為什么要一把鑰匙通開,而不是一個鑰匙一個門呢?我想這純粹是因為復雜性問題。一個鑰匙一個門當然更

安全,但是會牽扯好多問題。鑰匙 的產生,保管,獲得,歸還等等。其復雜性有可能隨同步方法的增加呈幾何級數增加,嚴重影響效率。這也算是一個權衡的問題吧。為了增加一點點安全性,導致效 率大大降低,是多么不可取啊。

另一個例子:

我們可以使用“電話亭”來比較對象鎖。假設有一個帶鎖的電話亭,當一個線程運行snychronized方法或者snychronized代碼塊時,它便進入電話亭并將它鎖起來。當另一個線程試圖運行同一個對象上的snychronized方法或者snychronized代碼塊時候,它無法打開電話亭的門,只能在門口等,知道第一個線程退出snychronized方法或者snychronized塊時并打開鎖時,它才有機會進入這個電話亭。

wait和notify方法例子:消費者和生產者

生產者將產品交給店員,而消費者從店員處取走產品,店員一次只能持有固定數目的產品,如果生產者生產了過多的產品,店員會叫生產者等一下,如果店中有空位放產品了再通知生產者繼續生產;如果店中沒有了產品,店員同樣會告訴消費者等一下,如果店中有產品了再通知消費者過來取。這里可能出現的問題有以下兩個:

1、生產者比消費者快,消費者會漏掉一些數據沒有取到。‘

2、消費者比生產者快,消費者會取相同的數據。

總結

以上是生活随笔為你收集整理的java snychronized_Java synchronized同步线程机制(三) | 学步园的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。