舉例解釋Java多線程編程中讀寫鎖的應用。本站提示廣大學習愛好者:(舉例解釋Java多線程編程中讀寫鎖的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是舉例解釋Java多線程編程中讀寫鎖的應用正文
以下示例為 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();
讀寫鎖是線程讀寫統一文件所須要用到的,讀寫鎖是甚麼器械在這裡不做過量的說明,可以本身去百度或谷歌去搜一下。
謹在此附上我本身寫的緩存體系的簡略完成,你從中也能悟出緩存完成的根本思惟
緩存外面稀有據就從緩存中取,沒有就給你從其他處所獲得。
package cn.com.scl.cache
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 緩存的完成,每一個線程只能取得他本身的緩存,也應當是單例的
* 本類沒有去完成單例,假如須要的話可以自行去完成
* @author scl
*
*/
public class CacheSystem {
private Map<String, Object> cache = new HashMap<String,Object>();
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public Object getData(String key){
//先從緩存中去取數據,先加上讀鎖
rwl.readLock().lock();
Object obj = null;
try{
obj = cache.get(key);
if(obj == null){
//先消除讀鎖,在上寫鎖(必需先消除讀鎖能力勝利上寫鎖)
rwl.readLock().unlock();
rwl.writeLock().lock();
//去數據庫取數據,再斷定一次能否為null,由於有能夠多個線程取得寫鎖
try{
if(obj == null){
obj = new String("obj is get from db");
}
}finally{
//先上讀鎖,然後再消除寫鎖(如許可以勝利完成,在消除寫鎖前取得讀鎖,寫鎖被升級--這翻譯的api上的)
rwl.readLock().lock();
rwl.writeLock().unlock();//消除寫鎖,讀鎖依然持有
}
}
}finally{
rwl.readLock().unlock();
}
return obj;
}
}