7.5重入读写锁( ReentrantReadWritelock)

 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 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值