Java共享锁和排它锁
以 ReentranReadWriteLock 读写锁为例
什么是共享锁和排它锁
- 排它锁,又称独占锁,独享锁 synchronized就是一个排它锁
- 共享锁,又称为读锁,获得共享锁后,可以查看,但无法删除和修改数 据, 其他线程此时业获取到共享锁,也可以查看但是 无法修改和 删除数据
- 共享锁和排它锁典型是ReentranReadWriteLock 其中,读锁是共享锁,写锁是 排它锁
读写锁的作用
在没有读写锁之前,我们使用的是ReentrantLock ,虽然我们保证了线程安全,,但是业浪费了一定的资源,多个读操作同时进行,是不会出现线程安全问题
读写锁的规则
-
读写锁只是一把锁,可以通过2种方式锁定,读锁定和写锁定
- 多个线程取请求读锁,都可以请求到的如果一个线程获取到了读锁,其他线程需要写锁,申请的写锁必须得等读锁释放总结 : 要么多读,要么一写,二者不可共存
ReentranReadWriteLock 具体用法
package com.yxl.po; import java.util.concurrent.locks.ReentrantReadWriteLock; public class a { //创建读写锁 private static ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock(); //创建读锁 private static ReentrantReadWriteLock.ReadLock readLock=reentrantReadWriteLock.readLock(); //创建写锁 private static ReentrantReadWriteLock.WriteLock writeLock=reentrantReadWriteLock.writeLock(); //读锁方法 private static void read(){ readLock.lock(); try { System.out.println(Thread.currentThread().getName()+"得到了读锁"); Thread.sleep(1000); }catch (Exception e){ }finally { System.out.println(Thread.currentThread().getName()+"释放读锁"); readLock.unlock(); } } //写锁方法 private static void write(){ writeLock.lock(); try { System.out.println(Thread.currentThread().getName()+"得到了写锁"); Thread.sleep(1000); }catch (Exception e){ }finally { System.out.println(Thread.currentThread().getName()+"释放写锁"); writeLock.unlock(); } } public static void main(String[] args) { new Thread(()->read(),"T1").start(); new Thread(()->read(),"T2").start(); new Thread(()->write(),"T3").start(); new Thread(()->write(),"T4").start(); } }
- 从运行结果可以、看到 读锁 线程1 和 2 都可以一起获取到 而写锁必须得获取释放,下一个线程才能获取
读锁和写锁的交互方式
- 插队: 不允许读锁插队
- 升降级 允许降级,不允许升级,
是否是公平策略 ,和 ReentranLock 一样 传入true ,false
- 底层设计思路和ReentranLock 一样
公平锁: 不允许插队
非公平锁:
- 写锁可以随时插队
- 读锁仅在等待队列头节点不是想获取写锁到时候可以插队
原文链接:https://blog.csdn.net/qq_41977838/article/details/106559658