与互斥锁定相比,读-写锁定允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(
writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(
reader 线程),读-写锁定利用了这一点。从理论上讲,与互斥锁定相比,使用读-写锁定所允许的并发性增强将带来更大的性能提高。在实践中,只有在多处理器上并且只在访问模式适用于共享数据时,才能完全实现并发性增强。
public class Test14 {
public static void main(String[] args) {
final LocalReadWriterTest lrw=new LocalReadWriterTest();
for(int i=0;i<3;i++){//开三个线程进行读取
new Thread(){
public void run(){
try {
lrw.readData();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
for(int i=0;i<3;i++){//开三个线程进行写入
Thread t=new Thread(){
public void run(){
try {
lrw.writeData(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
/*在 writer 释放写入锁定时,reader 和 writer 都处于等待状态,在这时要确定是授予读取锁定还是授予写入锁定。
Writer 优先比较普遍,因为预期写入所需的时间较短并且不那么频繁。Reader 优先不太普遍,因为如果 reader
正如预期的那样频繁和持久,那么它将导致对于写入操作来说较长的时延。公平或者“按次序”实现也是有可能的。 */
t.setPriority(7);//让"写"有优先的能力,因为如果读的时间太多或频繁的话,写就会一直延时等待,这样不利于及时性
t.start();
}
}
/**
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由jvm自己控制的
只要没有 writer,读取锁定可以由多个 reader 线程同时保持。写如锁定是独占的。
*/
static class LocalReadWriterTest{
ReadWriteLock rwl=new ReentrantReadWriteLock();
private Integer data;
public void readData() throws InterruptedException{
rwl.readLock().lock();//在读的操作中,可以有多个线程同时进行
System.out.println(Thread.currentThread().getName()+" :开始读取....");
Thread.sleep(1000);
try{
System.out.println(Thread.currentThread().getName()+" :"+data);
System.out.println(Thread.currentThread().getName()+" :读取完毕....");
}finally{
rwl.readLock().unlock();
}
}
public void writeData(int data) throws InterruptedException{
rwl.writeLock().lock();//在写的操作中,只能有一个线程进行,即独立完成整个写入的过程
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" :开始写入....");
try{
this.data=data;
System.out.println(Thread.currentThread().getName()+" 写入的值:"+data);
System.out.println(Thread.currentThread().getName()+" :写入完毕....");
}finally{
rwl.writeLock().unlock();
}
}
}
}
/*运行结果:
Thread-0 :开始读取....
Thread-1 :开始读取....
Thread-0 :null
Thread-0 :读取完毕....
Thread-1 :null
Thread-1 :读取完毕....
Thread-4 :开始写入....
Thread-4 写入的值:470
Thread-4 :写入完毕....
Thread-3 :开始写入....
Thread-3 写入的值:730
Thread-3 :写入完毕....
Thread-5 :开始写入....
Thread-5 写入的值:409
Thread-5 :写入完毕....
Thread-2 :开始读取....
Thread-2 :409
Thread-2 :读取完毕....
*/