国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

重入鎖

2019-11-08 19:38:03
字體:
來源:轉載
供稿:網友

java提供了一種內置的鎖機制來支持原子性:同步代碼塊 同步代碼塊包括兩部分: 1、鎖的對象引用 2、鎖保護的代碼塊 而每個Java對象都可以用作一個實現同步的鎖,這種鎖叫內置鎖(又叫監視器鎖): 線程在進入同步代碼塊之前會自動獲得鎖,并且在退出同步代碼塊時自動釋放鎖(無論是正常退出還是通過拋出異常退出) 另外:內置鎖是一種互斥鎖,即防止多個線程同一時刻訪問相同的共享資源。 內置鎖也是重入鎖

重入鎖的理解:所謂重入鎖,指的是以線程為單位,當一個線程獲取對象鎖之后,這個線程可以再次獲取已經由它自己持有的鎖。 即:指的是同一線程 外層函數獲得鎖之后 ,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。 案例:

public class StringUtilTest { //這里可以看到sayName與sayAge都加鎖,但調用 //sayName后在里面調用了sayAge,輸出正常,說明該鎖//是可以被該線程再次獲取的,即可重入 public synchronized void sayName(){ System.out.重入鎖的實現原理(其中一種): 每個重入鎖都有一個計數器和一個所有者線程。但計數器為0,即該鎖沒有被線程持有。 當一個線程請求一個未被持有的鎖時,JVM將記下鎖的持有者,并且將計數器置為1,。 如果該線程再次獲取這個鎖,計數器將遞增,而退出同步代碼塊時,計數器將遞減, 計數器遞減至0時,則釋放該鎖。 實例分析: 當如上代碼,有線程獲取sayName上的鎖時,此時計數器為1,在sayName中調用了 sayAge后,計數器遞增至2,sayAge執行完畢,計數器遞減至1,退出sayName后, 計數器為0,釋放該鎖。

以下示例為 java api并發庫中 ReentrantReadWriteLock自帶的實例,下面進行解讀 class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

void processCachedData() { rwl.readLock().lock();//@1 if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock();//@4 rwl.writeLock().lock();//@2 // Recheck state because another thread might have acquired // write lock and changed state before we did. if (!cacheValid) {//@3 data = … cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); rwl.writeLock().unlock(); // Unlock write, still hold read }

use(data); rwl.readLock().unlock();

} } //當有n多線程 使用同一CachedData 實例對象 調用processCachedData方法時,就會產生線程的并發問題. @1行,當有線程正在對數據進行 寫操作的時候,運行到@1行的線程要等待 寫操作的完成,因為第一個運行到@2的線程會加上鎖,然后對數據進行修改,期間不允許其他線程進行讀或者是寫的操作, 當寫完后,在該線程上加上讀鎖操作,以防止解寫鎖后,別的線程對數據再次進行寫時出錯. 在第一個運行到@2的線程之后的很多線程可能已經運行到了@4,當對數據修改好之后,解除掉寫鎖,別的線程就會執行到@2,這時第一個線程已經經數據修改好了,所以有了@3的判斷。 在編寫多線程程序的時候,要置于并發線程的環境下考慮,巧妙的運用ReentrantReadWriteLock,在運用時,注意鎖的降級, 寫入鎖中可以獲得讀鎖,讀鎖中不可以獲得寫入鎖,所以在上寫入鎖時,必須先將讀鎖進行解除,然后上寫鎖

使用時注意的幾個方面:    讀鎖是排寫鎖操作的,讀鎖不排讀鎖操作,多個讀鎖可以并發不阻塞。即在讀鎖獲取后和讀鎖釋放之前,寫鎖并不能被任何線程獲得,多個讀鎖同時作用期間,試圖獲取寫鎖的線程都處于等待狀態,當最后一個讀鎖釋放后,試圖獲取寫鎖的線程才有機會獲取寫鎖。    寫鎖是排寫鎖、排讀鎖操作的。當一個線程獲取到寫鎖之后,其他試圖獲取寫鎖和試圖獲取讀鎖的線程都處于等待狀態,直到寫鎖被釋放。 寫鎖是可以獲得讀鎖的,即:       rwl.writeLock().lock();       //在寫鎖狀態中,可以獲取讀鎖       rwl.readLock().lock();       rwl.writeLock().unlock();   讀鎖是不能夠獲得寫鎖的,如果要加寫鎖,本線程必須釋放所持有的讀鎖,即:      rwl.readLock().lock();       //……       //必須釋放掉讀鎖,才能夠加寫鎖       rwl.readLock().unlock();       rwl.writeLock().lock();


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 密云县| 丰都县| 疏附县| 宜兰市| 屯昌县| 永安市| 昆明市| 布拖县| 左权县| 庆元县| 孟州市| 祁阳县| 信阳市| 北京市| 太保市| 拉萨市| 射洪县| 博爱县| 承德市| 安西县| 西充县| 门头沟区| 汕尾市| 铜鼓县| 伊宁市| 井冈山市| 永登县| 灌云县| 霸州市| 盘山县| 宝应县| 台东县| 商南县| 道孚县| 陆丰市| 阳高县| 珠海市| 镶黄旗| 龙井市| 申扎县| 瓦房店市|