ReadWriteLock是继承ReantrantReadWriteLock的类,这就声明了一个重入读写锁,有点类似于ReentrantLock.
你可以通过以下的方法来初始化ReentrantReadWriteLock的实例。
ReentrantReadWriteLock():创建一个ReentrantReadWriteLock的实例。这个构造器类似于ReenReadWriteLock(false)。 ReentrantReadWritelock(booleanfair):创建一个ReentrantReadWriteLock的实例,并且明确指定的公平策略。当锁需要的序地执行时,需要设置为true。
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 Mapdictionary = new HashMap (); 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