7.5重入讀寫鎖( ReentrantReadWritelock)
阿新 • • 發佈:2019-02-02
Note 對於公平的有序策略,當前持有的鎖被釋放,或長時間等待的獨有寫的執行緒會被註冊寫的鎖;或一組讀的執行緒等待的時間比寫的執行緒來的長,那個這個組將會註冊讀的鎖。
當一個寫的鎖被持有或這裡已經有等待寫的鎖,那麼一個試圖請求公平的讀的鎖(不是重入的)會處於阻塞狀態。這個執行緒將不會請求讀的鎖,直到最老的等待寫的執行緒釋放寫的鎖。如果寫的執行緒無邊界地在等待,將一個或多個讀的執行緒作為長時間等待的執行緒在佇列中,這些讀的執行緒將會被註冊為讀的鎖。
一個執行緒嘗試去公平的寫的鎖將會處於阻塞狀態,除非讀和寫的鎖都是自由的。(非阻塞的tryLock()方法不會遵守這個公平的設定,如果有可能的話它會更快速的請求鎖,而不管等待執行緒情況如何。)
你可以用下面的方法來例項化這個類:
- ReentrantReadWriteLock.ReadLockreadLock():返回讀的鎖應用。
- ReentrantReadWriteLock.WriteLockwriteLock():返回寫的鎖的應用。
- 每一個巢狀ReadLock和WriteLock的類都繼承了Lock的介面和宣告自己的方法。然而,ReentrantReadWriteLock聲明瞭中添加了如下的方法:
- int getReadHoldCount():重入讀請求執行緒而持有的鎖的數量將會返回,當請求執行緒中並沒有持有鎖將返回0。一個讀的執行緒會持有每一個鎖的操作,而不是非鎖的操作。
- int getWriteHoldCount():重入寫請求執行緒,持有的鎖的數量將會返回,當請求執行緒中並沒有持有鎖將返回0。一個寫的執行緒會持有每一個鎖的操作,而不是非鎖的操作。
例子7-3主執行緒建立單詞和解釋的陣列,它們都宣告為final,因為它們將會用於內部類。之後建立一個Map儲存單詞和解釋,它含有重入的讀和寫的鎖。package com.owen.thread.chapter7; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Dictionary { public static void main(String[] args) { final String[] words = { "hypocalcemia", "prolixity", "assiduous", "indefatigable", "castellan" }; final String[] definitions = { "a deficiency of calcium in the blood", "unduly prolonged or drawn out", "showing great care, attention, and effort", "able to work or continue for a lengthy time without tiring", "the govenor or warden of a castle or fort" }; final Map<String, String> dictionary = new HashMap<String, String>(); ReadWriteLock rwl = new ReentrantReadWriteLock(true); final Lock rlock = rwl.readLock(); final Lock wlock = rwl.writeLock(); Runnable writer = () -> { for (int i = 0; i < words.length; i++) { wlock.lock(); try { dictionary.put(words[i], definitions[i]); System.out.println("writer storing " + words[i] + " entry"); } finally { wlock.unlock(); } try { Thread.sleep(1); } catch (InterruptedException ie) { System.err.println("writer " + "interrupted"); } } }; ExecutorService es = Executors.newFixedThreadPool(1); es.submit(writer); Runnable reader = () -> { while (true) { rlock.lock(); try { int i = (int) (Math.random() * words.length); System.out.println("reader accessing " + words[i] + ": " + dictionary.get(words[i]) + " entry"); } finally { rlock.unlock(); } } }; es = Executors.newFixedThreadPool(1); es.submit(reader); } }
一個可執行寫的執行緒被建立。它的run()方法遍歷單詞陣列。每一個寫的鎖將會被遍歷。當這個方法返回時,寫的執行緒就會執行寫的鎖和更新map。執行這些操作主要是通過map的put()方法。當新增資訊的新增單詞之後,寫的執行緒就會釋放,並且休眠一毫秒。執行器包含執行緒池和用於執行寫執行緒的運用。
一個寫的執行緒隨後被建立。它的run()方法重複地去獲取讀的鎖,通過隨機的進入map,輸出條目,和解鎖讀鎖。執行器包含執行緒池和用於執行寫執行緒的運用。
執行上面的程式碼,你可能會得到以下的結果:
reader accessing indefatigable: able to work or continue for a lengthy time without tiring entry
reader accessing prolixity: unduly prolonged or drawn out entry
reader accessing indefatigable: able to work or continue for a lengthy time without tiring entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing castellan: the govenor or warden of a castle or fort entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing prolixity: unduly prolonged or drawn out entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing prolixity: unduly prolonged or drawn out entry
reader accessing castellan: the govenor or warden of a castle or fort entry
reader accessing indefatigable: able to work or continue for a lengthy time without tiring entry
reader accessing indefatigable: able to work or continue for a lengthy time without tiring entry
reader accessing castellan: the govenor or warden of a castle or fort entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing castellan: the govenor or warden of a castle or fort entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing hypocalcemia: a deficiency of calcium in the blood entry
reader accessing assiduous: showing great care, attention, and effort entry
reader accessing assiduous: showing great care, attention, and effort entry