开发中遇到并发的问题一般会用到锁,Synchronized存在明显的一个性能问题就是读与读之间互斥;ReadWriteLock是JDK5中提供的读写分离锁。
读写分离锁可以有效地帮助减少锁竞争,以提升系统的性能。
ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。
而读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥;读写锁维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。下面从例子中来说明:读读共享,读写互斥,写写互斥。
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReentrantWriteReadLockTest {
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public void read(){
try{
readLock.lock();
System.out.println("线程"+Thread.currentThread().getName()+"进入");
Thread.sleep(1000);
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(1000);
System.out.println("线程"+Thread.currentThread().getName()+"退出");
}catch (InterruptedException e){
e.printStackTrace();
}
finally {
writeLock.unlock();
}
}
public static void main(String[] args) {
final ReentrantWriteReadLockTest reentrantWriteReadLockTest = new ReentrantWriteReadLockTest();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
reentrantWriteReadLockTest.read();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
reentrantWriteReadLockTest.read();
}
},"t2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
reentrantWriteReadLockTest.write();
}
},"t3");
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
reentrantWriteReadLockTest.write();
}
},"t4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
线程t1和t2可以同时进入,说明了读读共享!当我们启动线程t2和t3时,一个线程必须等待另一个线程退出,才能进入,说明了读写互斥!当我们启动线程t3和t4时,一个线程必须等待另一个线程退出,才能进入,说明了写写互斥!