- 相關(guān)推薦
java并發(fā)編程參考
在Java5.0之前,只有synchronized(內(nèi)置鎖)和volatile. Java5.0后引入了顯示鎖ReentrantLock.
ReentrantLock概況
ReentrantLock是可重入的鎖,它不同于內(nèi)置鎖, 它在每次使用都需要顯示的加鎖和解鎖, 而且提供了更高級的特性:公平鎖, 定時(shí)鎖, 有條件鎖, 可輪詢鎖, 可中斷鎖. 可以有效避免死鎖的活躍性問題.ReentrantLock實(shí)現(xiàn)了
Lock接口:
復(fù)制代碼 代碼如下:
public interface Lock {
//阻塞直到獲得鎖或者中斷
void lock();
//阻塞直到獲得鎖或者中斷拋異常
void lockInterruptibly() throws InterruptedException;
//只有鎖可用時(shí)才獲得,否則直接返回
boolean tryLock();
//只有鎖在指定時(shí)間內(nèi)可用時(shí)才獲得,否則直接返回,中斷時(shí)拋異常
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
//返回一個(gè)綁定在這個(gè)鎖上的條件
Condition newCondition();
}
Lock使用
復(fù)制代碼 代碼如下:
Lock lock = new ReentrantLock();
lock.lock();
try{
//更新對象狀態(tài)
}finally{
//這里注意,一定要有finally代碼塊去解鎖
//否則容易造成死鎖等活躍性問題
lock.unlock();
}
ReentrantLock特性
輪詢鎖的和定時(shí)鎖
可輪詢和可定時(shí)的鎖請求是通過tryLock()方法實(shí)現(xiàn)的,和無條件獲取鎖不一樣. ReentrantLock可以有靈活的容錯(cuò)機(jī)制.死鎖的很多情況是由于順序鎖引起的, 不同線程在試圖獲得鎖的時(shí)候阻塞,并且不釋放自己已經(jīng)持有的鎖, 最后造成死鎖. tryLock()方法在試圖獲得鎖的時(shí)候,如果該鎖已經(jīng)被其它線程持有,則按照設(shè)置方式立刻返回,而不是一直阻塞等下去,同時(shí)在返回后釋放自己持有的鎖.可以根據(jù)返回的結(jié)果進(jìn)行重試或者取消,進(jìn)而避免死鎖的發(fā)生.
公平性
ReentrantLock構(gòu)造函數(shù)中提供公平性鎖和非公平鎖(默認(rèn))兩種選擇。所謂公平鎖,線程將按照他們發(fā)出請求的順序來獲取鎖,不允許插隊(duì);但在非公平鎖上,則允許插隊(duì):當(dāng)一個(gè)線程發(fā)生獲取鎖的請求的時(shí)刻,如果這個(gè)鎖是可用的,那這個(gè)線程將跳過所在隊(duì)列里等待線程并獲得鎖。我們一般希望所有鎖是非公平的。因?yàn)楫?dāng)執(zhí)行加鎖操作時(shí),公平性將講由于線程掛起和恢復(fù)線程時(shí)開銷而極大的降低性能?紤]這么一種情況:A線程持有鎖,B線程請求這個(gè)鎖,因此B線程被掛起;A線程釋放這個(gè)鎖時(shí),B線程將被喚醒,因此再次嘗試獲取鎖;與此同時(shí),C線程也請求獲取這個(gè)鎖,那么C線程很可能在B線程被完全喚醒之前獲得、使用以及釋放這個(gè)鎖。這是種雙贏的局面,B獲取鎖的時(shí)刻(B被喚醒后才能獲取鎖)并沒有推遲,C更早地獲取了鎖,并且吞吐量也獲得了提高。在大多數(shù)情況下,非公平鎖的性能要高于公平鎖的性能。
可中斷獲鎖獲取操作
lockInterruptibly方法能夠在獲取鎖的同時(shí)保持對中斷的響應(yīng),因此無需創(chuàng)建其它類型的不可中斷阻塞操作。
讀寫鎖ReadWriteLock
ReentrantLock是一種標(biāo)準(zhǔn)的互斥鎖,每次最多只有一個(gè)線程能持有鎖。讀寫鎖不一樣,暴露了兩個(gè)Lock對象,其中一個(gè)用于讀操作,而另外一個(gè)用于寫操作。
復(fù)制代碼 代碼如下:
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading.
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing.
*/
Lock writeLock();
}
可選擇實(shí)現(xiàn):
1.釋放優(yōu)先
2.讀線程插隊(duì)
3.重入性
4.降級
5.升級
ReentrantReadWriteLock實(shí)現(xiàn)了ReadWriteLock接口,構(gòu)造器提供了公平鎖和非公平鎖兩種創(chuàng)建方式。讀寫鎖適用于讀多寫少的情況,可以實(shí)現(xiàn)更好的并發(fā)性。
示例
復(fù)制代碼 代碼如下:
public class ReadWriteMap{
private Mapmap;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
public ReadWriteMap(Mapmap) {
this.map = map;
}
public V get(K key) {
readLock.lock();
try {
return map.get(key);
} finally {
readLock.unlock();
}
}
public void put(K key, V value) {
writeLock.lock();
try {
map.put(key, value);
} finally {
writeLock.unlock();
}
}
}
【java并發(fā)編程參考】相關(guān)文章:
Java并發(fā)編程:深入剖析ThreadLocal09-20
java教程之Java編程基礎(chǔ)09-12
Java語言的編程特點(diǎn)03-18
Java編程學(xué)習(xí)示例07-31
java面向?qū)ο缶幊讨v解06-18
Java編程中異常處理的方法10-02
Java編程常見問題匯總06-12
Java編程中獲取路徑的方法09-06