首页 > 代码库 > J.U.C重入锁
J.U.C重入锁
ReentrantLock重入锁
ReentrantLock是Java并发包中互斥锁,它有公平锁和非公平锁两种实现方式, 重入的意思就是,如果已经获得了锁,如果执行期间还需要获得这个锁的话,会直接获得所,不会被阻塞,获得锁的次数加1;每执行一次unlock,持有锁的次数减1,当为0时释放锁。这点,Synchronized 具有同样语义。
Sync在ReentrantLock中有两种子类:非公平锁NonfairSync、公平锁FairSync,默认情况下为非公平锁。
先判断锁的状态,通过CAS来抢占,抢占成功,直接返回true
如果锁的持有者线程为当前线程(偏向锁)的话,则通过累加状态标识重入次数,因为没有竞争,所以通过setStatus修改。否则返回false,入队等待获取锁。
当前线程释放,releases表示释放次数(重入)。如果为0独占线程设为null。最后更新状态
lock()方法
非公平锁NonfairSync
线程进入先抢占锁,通过CAS操作compareAndSetState(0, 1)方法。0表示尚未有线程持有该锁;>=1则表示存在线程持有该锁,并重入对应次数。参考AbstractQueuedSynchronizer类。
公平锁FairSync:
getState==0没有线程持有该锁,并且通过!hasQueuedPredecessors()判断当前等待队列没有前继线程(也就是说,没有比我优先级更高的线程在请求锁了)获取锁的情况下,通过CAS抢占锁,并设置自己为锁的当前拥有者, 线程重入通过累加状态位标记重入次数。
ReentrantReadWriteLock
支持与 ReentrantLock 类似语义的 ReadWriteLock 实现。
例子一:读写一个共享数据的操作
例子二:读写集合的操作,用于读多写少的情况。
测试例子二:三分之一线程写任务,其余模拟随机读任务key1-3保证读不为空。
J.U.C重入锁