锁(五):读写锁
- 读写锁特性
特性:写写互斥、读写互斥、读读共享 锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级的特性
- 案例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,下一步,可以获取到锁,说明读读是共享的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~