Java多线程之ReentrantReadWriteLock

        一、锁的种类和含义        

        Java的concurrent并发包中,存在两种类型的锁,即共享锁和排它锁,后者也叫做独占锁。

        共享锁是指某一时刻锁可以被多个线程同时拥有,这些线程同时共享该锁。而排它锁则是指锁在某一时刻只能被一个线程拥有,任何想要获得该锁的线程,必须等待的锁的所有者释放后才可以。

        二、ReentrantReadWriteLock的含义

        ReentrantReadWriteLock是Java中的一种读写锁,它既不是完全的共享锁,也不是完全的排它锁。它实际上是一种混合形式的锁,既包含共享锁,同时也包含排它锁。

        这么做是为了什么呢?我们知道,很多情况下有这样一种业务场景,即对于一块数据,或者一个对象,即存在需要读取的时候,也存在需要修改,即写入的时候。那么,如果对于这种应用场景,如果是只用共享锁,同一时刻,允许多个线程读取和写入数据,那么数据操作的原子性就无法得到保证,在多并发的情况下,数据往往就是紊乱的;如果是只用排它锁,即某一线程读取的时候,即不允许其它线程写入,也不允许其它线程读取,这样是能保证数据操作的原子性,得到正确的数据,那么性能也随之降低了。

        所以,在兼顾数据操作的原子性和读写性能二者的情况下,一种同时融合共享锁和排它锁的混合锁的产生,就显得特别有意义了。这就是我们本文将要阐述的读写锁ReentrantReadWriteLock。

        它在读取数据或对象的时候使用读锁,即一种对读共享同时读写排它的锁,允许多个线程同时读取数据,但是不允许其它线程修改数据;而在修改数据或对象时使用写锁,一种完全的排它锁,既不允许 其它线程读取数据,也不允许其他线程修改数据。这样,数据操作的原子性和性能同时得到了考虑。

        三、ReentrantReadWriteLock的定义及实现

        ReentrantReadWriteLock实现了Java中的ReadWriteLock接口。

        四、ReentrantReadWriteLock的使用方式及代码示例

        ReentrantReadWriteLock的使用方式如下:

        首先,需要构造一个ReentrantReadWriteLock对象rrwl。代码如下:

// 构造ReentrantReadWriteLock对象rrwl
	private ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
        其次,需要获取ReentrantReadWriteLock对象rrwl的读锁readLock和写锁writeLock。代码如下:
// 获取读锁readLock:可被多个读线程共享,但是会排斥所有的写线程
	private Lock readLock = rrwl.readLock();
	
	// 获取写锁writeLock:排斥所有的读线程和其它写线程
	private Lock writeLock = rrwl.writeLock();
        然后,读锁的使用方法如下:

// 读锁的使用
	public Object readObject() {
		Object object = null;

		// 利用读锁readLock获取读锁
		readLock.lock();
		try {

			// 此处为业务代码
			object = new Object();

		} finally {

			// 利用读锁readLock释放读锁
			readLock.unlock();
		}

		return object;
	}
        最后,写锁的使用方法如下:

// 写锁的使用
	public void writeObject(Object object) {

		// 利用写锁writeLock获取写锁
		writeLock.lock();
		try {
			// 此处为业务代码
		} finally {
			// 利用写锁writeLock释放写锁
			writeLock.unlock();
		}

	}




上一篇:Spark源码分析之五:Task调度(一)


下一篇:HBase源码分析之compact请求发起时机、判断条件等详情(二)