1. 程式人生 > >7.5重入讀寫鎖( ReentrantReadWritelock)

7.5重入讀寫鎖( ReentrantReadWritelock)

Note 對於公平的有序策略,當前持有的鎖被釋放,或長時間等待的獨有寫的執行緒會被註冊寫的鎖;或一組讀的執行緒等待的時間比寫的執行緒來的長,那個這個組將會註冊讀的鎖。

     當一個寫的鎖被持有或這裡已經有等待寫的鎖,那麼一個試圖請求公平的讀的鎖(不是重入的)會處於阻塞狀態。這個執行緒將不會請求讀的鎖,直到最老的等待寫的執行緒釋放寫的鎖。如果寫的執行緒無邊界地在等待,將一個或多個讀的執行緒作為長時間等待的執行緒在佇列中,這些讀的執行緒將會被註冊為讀的鎖。

     一個執行緒嘗試去公平的寫的鎖將會處於阻塞狀態,除非讀和寫的鎖都是自由的。(非阻塞的tryLock()方法不會遵守這個公平的設定,如果有可能的話它會更快速的請求鎖,而不管等待執行緒情況如何。)

      你可以用下面的方法來例項化這個類:

  •         ReentrantReadWriteLock.ReadLockreadLock():返回讀的鎖應用。
  •         ReentrantReadWriteLock.WriteLockwriteLock():返回寫的鎖的應用。
  • 每一個巢狀ReadLock和WriteLock的類都繼承了Lock的介面和宣告自己的方法。然而,ReentrantReadWriteLock聲明瞭中添加了如下的方法:
  •         int getReadHoldCount():重入讀請求執行緒而持有的鎖的數量將會返回,當請求執行緒中並沒有持有鎖將返回0。一個讀的執行緒會持有每一個鎖的操作,而不是非鎖的操作。
  •         int getWriteHoldCount():重入寫請求執行緒,持有的鎖的數量將會返回,當請求執行緒中並沒有持有鎖將返回0。一個寫的執行緒會持有每一個鎖的操作,而不是非鎖的操作。
為了驗證ReadWriteLock和ReentrantReadWriteLock,例子7-3實現了一個應用程式,寫的執行緒會填充單詞的定義條目,讀的執行緒會不斷的訪問並隨機輸出。

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);
	}

}
例子7-3主執行緒建立單詞和解釋的陣列,它們都宣告為final,因為它們將會用於內部類。之後建立一個Map儲存單詞和解釋,它含有重入的讀和寫的鎖。
一個可執行寫的執行緒被建立。它的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