您现在的位置:首页 >> 前端 >> 内容

重入读写锁(ReentrantReadWritelock)详解

时间:2018/1/2 11:18:46 点击:

  核心提示:ReadWriteLock是继承ReantrantReadWriteLock的类,这就声明了一个重入读写锁,有点类似于ReentrantLock.你可以通过以下的方法来初始化ReentrantRead...

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

作者:网络 来源:owen_willi