首页 > 代码库 > J.U.C重入锁

J.U.C重入锁

ReentrantLock重入锁

技术分享

ReentrantLockJava并发包中互斥锁,它有公平锁和非公平锁两种实现方式, 重入的意思就是,如果已经获得了锁,如果执行期间还需要获得这个锁的话,会直接获得所,不会被阻塞,获得锁的次数加1;每执行一次unlock,持有锁的次数减1,当为0时释放锁。这点,Synchronized 具有同样语义。

技术分享

技术分享

技术分享

 

SyncReentrantLock中有两种子类:非公平锁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重入锁