Java ReadWriteLock
开发中遇到并发的问题一般会用到锁,Synchronized存在明显的一个性能问题就是读与读之间互斥;ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提升系统的性能。**ReadWriteLock**管理一组锁,一个是只读的锁,一个是写锁。
Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。
而读写锁**ReentrantReadWriteLock**:读读共享,读写互斥,写写互斥; 读写锁维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。
从源码中可以看出,读写锁中同样依赖队列同步器Sync(AQS)实现同步功能,而读写状态就是其同步器的同步状态。
下面从例子中来说明:读读共享,读写互斥,写写互斥。
代码如下:
public class ReentrantWriteReadLockTest {ReentrantReadWriteLock lock = new ReentrantReadWriteLock();ReadLock readLock = lock.readLock();WriteLock writeLock = lock.writeLock();public void read(){try {readLock.lock();System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");Thread.sleep(3000);System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");} catch (InterruptedException e) {e.printStackTrace();}finally{readLock.unlock();}}public void write(){try {writeLock.lock();System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");Thread.sleep(3000);System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");} catch (InterruptedException e) {e.printStackTrace();}finally{writeLock.unlock();}}public static void main(String[] args) {final ReentrantWriteReadLockTest wr = new ReentrantWriteReadLockTest();Thread t1 = new Thread(new Runnable() {public void run() {wr.read();}}, "t1");Thread t2 = new Thread(new Runnable() {public void run() {wr.read();}}, "t2");Thread t3 = new Thread(new Runnable() {public void run() {wr.write();}}, "t3");Thread t4 = new Thread(new Runnable() {public void run() {wr.write();}}, "t4");t1.start();t2.start();//t3.start();//t4.start();}}
当启动线程t1和t2时,结果如下:
线程t1和t2可以同时进入,说明了读读共享!
当启动线程t2和t3时,结果如下:
一个线程必须等待另一个线程退出,才能进入,说明了读写互斥!
当启动线程t3和t4时,结果如下:
一个线程必须等待另一个线程退出,才能进入,说明了写写互斥!
