锁(五):读写锁
- 读写锁特性
特性:写写互斥、读写互斥、读读共享
锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级的特性
- 案例1
public class ReentrantReadWriteLockDemo {
private int i = 0;
private int j = 0;
// 获取锁
private ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
// 使用读锁
public void out(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"i的值====》"+i + "j的值====》"+j);
}finally {
readLock.unlock();
}
}
// 使用写锁
public void inCreate() {
writeLock.lock();
try {
i++;
Thread.sleep(500L);
j++;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
}
// 测试
public static void main(String[] args) {
ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();
// 测试1,3个线程,先写后读
for (int i = 0; i < 3; i++) {
new Thread(()->{
reentrantReadWriteLockDemo.inCreate();
reentrantReadWriteLockDemo.out();
}).start();
}
}
}
# 控制台结果:
Thread-2i的值====》3j的值====》3
Thread-1i的值====》3j的值====》3
Thread-0i的值====》3j的值====》3
-
debug调试
-
线程0拿到写锁,释放写锁
-
执行完毕
-
之后执行线程1和线程2
-
案例2
public class ReentrantReadWriteLockDemo {
private int i = 0;
private int j = 0;
// 获取锁
private ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
// 使用读锁
public void out(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"i的值====》"+i + "j的值====》"+j);
}finally {
readLock.unlock();
}
}
// 使用写锁
public void inCreate() {
writeLock.lock();
try {
i++;
Thread.sleep(500L);
j++;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
}
// 测试
public static void main(String[] args) {
ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();
// 测试2,2个线程,先读后写
new Thread(()->{
reentrantReadWriteLockDemo.out();
},"读线程").start();
new Thread(()->{
reentrantReadWriteLockDemo.inCreate();
},"写线程").start();
}
}
-
debug调试
-
如下:读线程获取到锁,但还没有释放
-
切换到写线程,下一步时报错如下,说明读写是互斥的
-
案例3
public class ReentrantReadWriteLockDemo {
private int i = 0;
private int j = 0;
// 获取锁
private ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
// 使用读锁
public void out(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"i的值====》"+i + "j的值====》"+j);
}finally {
readLock.unlock();
}
}
// 使用写锁
public void inCreate() {
writeLock.lock();
try {
i++;
Thread.sleep(500L);
j++;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
}
// 测试
public static void main(String[] args) {
ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo();
// 测试3,2个线程,读读操作
new Thread(()->{
reentrantReadWriteLockDemo.out();
},"读线程1").start();
new Thread(()->{
reentrantReadWriteLockDemo.out();
},"读线程2").start();
}
}
- debug调试
- 首先读线程1获取到锁,但还没有释放
- 切换到读线程2,下一步,可以获取到锁,说明读读是共享的