ReentrantReadWriteLock读写锁的特点:
1、允许多个读线程同时访问,读访问时,写锁不能访问
2、当有写线程访问时,其他的读和写线程都不能够访问
3、编程方式相对于使用等待通知机制:写的时候,其他的读写都阻塞,保证每次读取到的都是最新的数据
4、在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量
ReentrantReadWriteLock其实实现的是ReadWriteLock接口
使用的标准方式
readLock.lock();
try {
//DoSomeThing
}finally {
readLock.unlock();
}
示例一:一个线程读的时候,其他的读线程也能读
public class MyReentrantWriteReadLock {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
static ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
new Thread(()->{
readLock.lock();
try {
for (Integer item : list) {
Thread.sleep(200);
System.out.println(Thread.currentThread().getName()+":"+item);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
readLock.unlock();
}
}).start();
new Thread(()->{
readLock.lock();
try {
for (Integer item : list) {
Thread.sleep(200);
System.out.println(Thread.currentThread().getName()+":"+item);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
readLock.unlock();
}
}).start();
}
}
执行结果:两个线程交替执行
Thread-0:1
Thread-1:1
Thread-0:2
Thread-1:2
Thread-0:3
Thread-1:3
Thread-0:4
Thread-1:4
示例二:一个线程读,其他的写线程阻塞,一个线程写,其他读写都阻塞
public class MyReentrantWriteReadLock2 {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
static ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
public static void main(String[] args) throws InterruptedException {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
//先获取读锁,读取完毕之后才能写
new Thread(()->{
readLock.lock();
try {
Thread.sleep(1000);
for (Integer item : list) {
System.out.println(Thread.currentThread().getName()+":"+item);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
readLock.unlock();
}
}).start();
Thread.sleep(10);
//写锁
new Thread(()->{
writeLock.lock();
try {
Thread.sleep(1000);
System.out.println("先获取读锁,读锁执行完之后,写锁才开始");
list.add(5);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
}).start();
Thread.sleep(10);
new Thread(()->{
readLock.lock();
try {
System.out.println("写锁执行完之后,读锁才开始");
for (Integer item : list) {
System.out.println(Thread.currentThread().getName()+":"+item);
}
//} catch (InterruptedException e) {
// e.printStackTrace();
}finally {
readLock.unlock();
}
}).start();
}
}
执行结果:
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
现获取读锁,读锁执行完之后,写锁才开始
写锁执行完之后,读锁才开始
Thread-2:1
Thread-2:2
Thread-2:3
Thread-2:4
Thread-2:5