展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

锁(五):读写锁

  • 读写锁特性
特性:写写互斥、读写互斥、读读共享
锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级的特性
  • 案例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,下一步,可以获取到锁,说明读读是共享的
posted @   DogLeftover  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示