舉例解釋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; } }