當前位置:首頁 » 編程語言 » 讀寫鎖java

讀寫鎖java

發布時間: 2022-11-17 15:36:55

java 如何判斷一個對象被其它線程讀或寫鎖定如果鎖定則所在方法return

你需要一種非阻塞式的鎖。java.util.cocurrent包中的ReentrantReadWriteLock就提供了可重入的讀寫鎖機制。

=newReentrantReadWriteLock();//讀寫鎖

publicbooleanread(){
//嘗試獲取讀鎖
if(rwl.readLock().tryLock()){
//讀資源
returntrue;
}else{//獲取讀鎖失敗
returnfalse;//立即返回
}
}

publicbooleanwrite(){
//嘗試獲取寫鎖
if(rwl.writeLock().tryLock()){
//寫資源
returntrue;
}else{//獲取寫鎖失敗
returnfalse;//立即返回
}
}

㈡ 什麼是讀寫鎖請用java設計一個簡單的讀寫鎖

一個讀寫鎖支持多個線程同時訪問一個對象,但是在同一時刻只有一個線程可以修改此對象,並且在訪問進行時不能修改

RandomAccessFile fis = new RandomAccessFile("shm.lock","rw");
// 獲得文件通道
FileChannel lockfc = fis.getChannel();
// 獲得文件的獨占鎖,該方法不產生堵塞,立刻返回
FileLock flock = lockfc.tryLock();
// 如果為空,則表明已經有應用佔有該鎖
if(flock == null) {
...// 不能執行寫操作
}
else {
...// 可以執行寫操作
}
該鎖會在應用異常退出後自動釋放,這正是該處所需要的方法。

㈢ java怎麼設置獲取讀寫鎖超時時間

1 package bing.test;
2
3 import java.util.concurrent.locks.Lock;
4 import java.util.concurrent.locks.ReadWriteLock;
5 import java.util.concurrent.locks.ReentrantReadWriteLock;
6
7 public class UpgradeLock{
8 private UpgradeLock(){ }
9 private final static ReadWriteLock rwlock =new ReentrantReadWriteLock();
10 private final static Lock read=rwlock.readLock();
11 private final static Lock write=rwlock.writeLock();
12
13
14 public static void main(String[] args){
15 log(getReadLock());
16 log(getWriteLock());
17 }
18
19
20 public static boolean getReadLock()
21 {
22 try{
23 int time = 0;
24 // 設置超時時間為5秒,獲取Lock,
25 //如果返回false(即獲取失敗)則等待直到超時,然後返回獲取lock的狀態
26 while(!read.tryLock() && ++time < 5){
27 Thread.sleep(1000);
28 log(time);
29 }
30 return read.tryLock();
31 }catch(Exception e)
32 {
33 e.printStackTrace();
34 return false;
35 }
36 }
37 public static boolean getWriteLock()
38 {
39 try{
40 int time = 0;
41 // 設置超時時間為5秒,獲取Lock,
42 //如果返回false(即獲取失敗)則等待直到超時,然後返回獲取lock的狀態
43 while(!write.tryLock() && ++time < 5){
44 Thread.sleep(1000);
45 log(time);
46 }
47 return read.tryLock();
48 }catch(Exception e)
49 {
50 e.printStackTrace();
51 return false;
52 }
53 }
54 public static void log(Object m){
55 System.out.println(m);
56 }
57 }

㈣ Java:讀鎖的作用在哪裡呢

讀鎖能保證內存可見性,保證這個變數被寫鎖修改過以後能同步到主內存中,讀鎖內讀到的變數是該變數的最新值,避免臟讀

㈤ 在java中有哪些鎖

給你整理了Java中的一些鎖:

  • 公平鎖/非公平鎖

  • 可重入鎖

  • 獨享鎖/共享鎖

  • 互斥鎖/讀寫鎖

  • 樂觀鎖/悲觀鎖

  • 分段鎖

  • 偏向鎖/輕量級鎖/重量級鎖

  • 自旋鎖

  • 上面是很多鎖的名詞,這些分類並不是全是指鎖的狀態,有的指鎖的特性,有的指鎖的設計

㈥ java中讀鎖的作用,為什麼要用讀鎖

讀寫鎖:ReentrantReadWriteLock
如果有很多線程從一個數據結構中讀取數據,而很少的線程修改數據,那麼就用讀寫鎖。

分別得到讀鎖和寫鎖:
ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();
ReadLock readL = rrwl.readLock();
WriteLock writeL = rrwl.writeLock();

讀鎖與讀鎖不互斥,讀鎖與寫鎖互斥,寫鎖與寫鎖互斥。
用於優化性能,提高讀寫速度。

㈦ java 讀寫鎖 線程被阻塞後,一旦解鎖,會自動運行么

不太清楚你的描述,如果你用的是synchronized這樣的關鍵詞去鎖住某塊代碼,那麼這個鎖在其他佔用解除後,你的線程還會繼續往synchronized裡面的代碼執行的,線程因為鎖安全鎖而阻塞在synchronized那裡的話,當然會繼續往下執行

㈧ java 哪個鎖是非重入的

讀寫鎖 ReadWriteLock讀寫鎖維護了一對相關的鎖,一個用於只讀操作,一個用於寫入操作。只要沒有writer,讀取鎖可以由多個reader線程同時保持。寫入鎖是獨占的。
互斥鎖一次只允許一個線程訪問共享數據,哪怕進行的是只讀操作;讀寫鎖允許對共享數據進行更高級別的並發訪問:對於寫操作,一次只有一個線程(write線程)可以修改共享數據,對於讀操作,允許任意數量的線程同時進行讀取。
與互斥鎖相比,使用讀寫鎖能否提升性能則取決於讀寫操作期間讀取數據相對於修改數據的頻率,以及數據的爭用——即在同一時間試圖對該數據執行讀取或寫入操作的線程數。
讀寫鎖適用於讀多寫少的情況。
可重入讀寫鎖 ReentrantReadWriteLock
屬性ReentrantReadWriteLock 也是基於 AbstractQueuedSynchronizer 實現的,它具有下面這些屬性(來自Java doc文檔):

* 獲取順序:此類不會將讀取者優先或寫入者優先強加給鎖訪問的排序。

* 非公平模式(默認):連續競爭的非公平鎖可能無限期地推遲一個或多個reader或writer線程,但吞吐量通常要高於公平鎖。
* 公平模式:線程利用一個近似到達順序的策略來爭奪進入。當釋放當前保持的鎖時,可以為等待時間最長的單個writer線程分配寫入鎖,如果有一組等待時間大於所有正在等待的writer線程的reader,將為該組分配讀者鎖。
* 試圖獲得公平寫入鎖的非重入的線程將會阻塞,除非讀取鎖和寫入鎖都自由(這意味著沒有等待線程)。

* 重入:此鎖允許reader和writer按照 ReentrantLock 的樣式重新獲取讀取鎖或寫入鎖。在寫入線程保持的所有寫入鎖都已經釋放後,才允許重入reader使用讀取鎖。
writer可以獲取讀取鎖,但reader不能獲取寫入鎖。
* 鎖降級:重入還允許從寫入鎖降級為讀取鎖,實現方式是:先獲取寫入鎖,然後獲取讀取鎖,最後釋放寫入鎖。但是,從讀取鎖升級到寫入鎖是不可能的。
* 鎖獲取的中斷:讀取鎖和寫入鎖都支持鎖獲取期間的中斷。
* Condition 支持:寫入鎖提供了一個 Condition 實現,對於寫入鎖來說,該實現的行為與 ReentrantLock.newCondition() 提供的Condition 實現對 ReentrantLock 所做的行為相同。當然,此 Condition 只能用於寫入鎖。
讀取鎖不支持 Condition,readLock().newCondition() 會拋出 UnsupportedOperationException。
* 監測:此類支持一些確定是讀取鎖還是寫入鎖的方法。這些方法設計用於監視系統狀態,而不是同步控制。

實現AQS 回顧在之前的文章已經提到,AQS以單個 int 類型的原子變數來表示其狀態,定義了4個抽象方法( tryAcquire(int)、tryRelease(int)、tryAcquireShared(int)、tryReleaseShared(int),前兩個方法用於獨占/排他模式,後兩個用於共享模式 )留給子類實現,用於自定義同步器的行為以實現特定的功能。
對於 ReentrantLock,它是可重入的獨占鎖,內部的 Sync 類實現了 tryAcquire(int)、tryRelease(int) 方法,並用狀態的值來表示重入次數,加鎖或重入鎖時狀態加 1,釋放鎖時狀態減 1,狀態值等於 0 表示鎖空閑。
對於 CountDownLatch,它是一個關卡,在條件滿足前阻塞所有等待線程,條件滿足後允許所有線程通過。內部類 Sync 把狀態初始化為大於 0 的某個值,當狀態大於 0 時所有wait線程阻塞,每調用一次 countDown 方法就把狀態值減 1,減為 0 時允許所有線程通過。利用了AQS的共享模式。
現在,要用AQS來實現 ReentrantReadWriteLock。
一點思考問題
* AQS只有一個狀態,那麼如何表示 多個讀鎖 與 單個寫鎖 呢?
* ReentrantLock 里,狀態值表示重入計數,現在如何在AQS里表示每個讀鎖、寫鎖的重入次數呢?
* 如何實現讀鎖、寫鎖的公平性呢?

㈨ Java鎖有哪些種類,以及區別

一、公平鎖/非公平鎖

公平鎖是指多個線程按照申請鎖的順序來獲取鎖。

非公平鎖是指多個線程獲取鎖的順序並不是按照申請鎖的順序,有可能後申請的線程比先申請的線程優先獲取鎖。有可能,會造成優先順序反轉或者飢餓現象。

對於Java ReentrantLock而言,通過構造函數指定該鎖是否是公平鎖,默認是非公平鎖。非公平鎖的優點在於吞吐量比公平鎖大。

對於Synchronized而言,也是一種非公平鎖。由於其並不像ReentrantLock是通過AQS的來實現線程調度,所以並沒有任何辦法使其變成公平鎖。

二、可重入鎖

可重入鎖又名遞歸鎖,是指在同一個線程在外層方法獲取鎖的時候,在進入內層方法會自動獲取鎖。說的有點抽象,下面會有一個代碼的示例。

對於Java ReentrantLock而言, 他的名字就可以看出是一個可重入鎖,其名字是Re entrant Lock重新進入鎖。

對於Synchronized而言,也是一個可重入鎖。可重入鎖的一個好處是可一定程度避免死鎖。

synchronized void setA() throws Exception{

Thread.sleep(1000);

setB();

}

synchronized void setB() throws Exception{

Thread.sleep(1000);

}

上面的代碼就是一個可重入鎖的一個特點,如果不是可重入鎖的話,setB可能不會被當前線程執行,可能造成死鎖。

三、獨享鎖/共享鎖

獨享鎖是指該鎖一次只能被一個線程所持有。

共享鎖是指該鎖可被多個線程所持有。

對於Java
ReentrantLock而言,其是獨享鎖。但是對於Lock的另一個實現類ReadWriteLock,其讀鎖是共享鎖,其寫鎖是獨享鎖。

讀鎖的共享鎖可保證並發讀是非常高效的,讀寫,寫讀 ,寫寫的過程是互斥的。

獨享鎖與共享鎖也是通過AQS來實現的,通過實現不同的方法,來實現獨享或者共享。

對於Synchronized而言,當然是獨享鎖。

四、互斥鎖/讀寫鎖

上面講的獨享鎖/共享鎖就是一種廣義的說法,互斥鎖/讀寫鎖就是具體的實現。

互斥鎖在Java中的具體實現就是ReentrantLock

讀寫鎖在Java中的具體實現就是ReadWriteLock

五、樂觀鎖/悲觀鎖

樂觀鎖與悲觀鎖不是指具體的什麼類型的鎖,而是指看待並發同步的角度。

悲觀鎖認為對於同一個數據的並發操作,一定是會發生修改的,哪怕沒有修改,也會認為修改。因此對於同一個數據的並發操作,悲觀鎖採取加鎖的形式。悲觀的認為,不加鎖的並發操作一定會出問題。

樂觀鎖則認為對於同一個數據的並發操作,是不會發生修改的。在更新數據的時候,會採用嘗試更新,不斷重新的方式更新數據。樂觀的認為,不加鎖的並發操作是沒有事情的。

從上面的描述我們可以看出,悲觀鎖適合寫操作非常多的場景,樂觀鎖適合讀操作非常多的場景,不加鎖會帶來大量的性能提升。

悲觀鎖在Java中的使用,就是利用各種鎖。

樂觀鎖在Java中的使用,是無鎖編程,常常採用的是CAS演算法,典型的例子就是原子類,通過CAS自旋實現原子操作的更新。

六、分段鎖

分段鎖其實是一種鎖的設計,並不是具體的一種鎖,對於ConcurrentHashMap而言,其並發的實現就是通過分段鎖的形式來實現高效的並發操作。

我們以ConcurrentHashMap來說一下分段鎖的含義以及設計思想,ConcurrentHashMap中的分段鎖稱為Segment,它即類似於HashMap(JDK7與JDK8中HashMap的實現)的結構,即內部擁有一個Entry數組,數組中的每個元素又是一個鏈表;同時又是一個ReentrantLock(Segment繼承了ReentrantLock)。

當需要put元素的時候,並不是對整個hashmap進行加鎖,而是先通過hashcode來知道他要放在那一個分段中,然後對這個分段進行加鎖,所以當多線程put的時候,只要不是放在一個分段中,就實現了真正的並行的插入。

但是,在統計size的時候,可就是獲取hashmap全局信息的時候,就需要獲取所有的分段鎖才能統計。

分段鎖的設計目的是細化鎖的粒度,當操作不需要更新整個數組的時候,就僅僅針對數組中的一項進行加鎖操作。

七、偏向鎖/輕量級鎖/重量級鎖

這三種鎖是指鎖的狀態,並且是針對Synchronized。在Java
5通過引入鎖升級的機制來實現高效Synchronized。這三種鎖的狀態是通過對象監視器在對象頭中的欄位來表明的。

偏向鎖是指一段同步代碼一直被一個線程所訪問,那麼該線程會自動獲取鎖。降低獲取鎖的代價。

輕量級鎖是指當鎖是偏向鎖的時候,被另一個線程所訪問,偏向鎖就會升級為輕量級鎖,其他線程會通過自旋的形式嘗試獲取鎖,不會阻塞,提高性能。

重量級鎖是指當鎖為輕量級鎖的時候,另一個線程雖然是自旋,但自旋不會一直持續下去,當自旋一定次數的時候,還沒有獲取到鎖,就會進入阻塞,該鎖膨脹為重量級鎖。重量級鎖會讓其他申請的線程進入阻塞,性能降低。

八、自旋鎖

在Java中,自旋鎖是指嘗試獲取鎖的線程不會立即阻塞,而是採用循環的方式去嘗試獲取鎖,這樣的好處是減少線程上下文切換的消耗,缺點是循環會消耗CPU。

典型的自旋鎖實現的例子,可以參考自旋鎖的實現

熱點內容
安卓電腦如何連手機熱點 發布:2025-01-13 19:40:52 瀏覽:142
pythonnumexpr 發布:2025-01-13 19:34:56 瀏覽:489
linuxpython版本查看 發布:2025-01-13 19:18:37 瀏覽:741
寶馬三系的哪個配置走量 發布:2025-01-13 19:12:14 瀏覽:695
區域網如何訪問伺服器 發布:2025-01-13 18:56:24 瀏覽:189
javaarraylist訪問 發布:2025-01-13 18:56:10 瀏覽:671
如何確定膠體是否配置成功 發布:2025-01-13 18:46:07 瀏覽:73
fgo緩存多大 發布:2025-01-13 18:42:13 瀏覽:972
能緩解壓力的水果 發布:2025-01-13 18:15:36 瀏覽:391
怎麼把文件壓縮成文件 發布:2025-01-13 18:15:33 瀏覽:610