Java ReentrantLock锁机制源码篇

2017-10-14  本文已影响46人  SMSM

接上文Java ReentrantLock锁机制概念篇

三、源码篇

终于可以看源码了,这个还是大家自己个儿看吧。推荐的解读顺序是:

  1. 锁实现 与 管理阻塞线程(独占锁:ReentrantLock)
  2. 线程等待await / 通知signal(ReentrantLock中 newCondition())
  3. 独占锁和共享锁(共享锁:CountDownLatch、ReentrantReadWriteLock)
  4. 线程中断interrupt(1和2过程中的中断处理)
  5. 案例 LinkedBlockingQueue

如果实在枯燥难看,下翻流程图部分,助你一臂之力。

类图

ReentrantLock类图

流程图

lock()

lock()代码流程图

unlock()

unlock()代码流程图

condition.await()

condition.await()代码流程图

condition.signal()

condition.signal()代码流程图

看源码的可借鉴的地方,看源码学习、借鉴如何做设计?我觉得比较好的地方分享给大家。

共享锁
锁的可重入性
写法方面
设计模式

推荐一篇文章 http://blog.csdn.net/fw0124/article/details/6672522

再读ReentrantLock源码

  1. 内部维持两个链表,阻塞链表、等待链表。
  2. await时,记录当前Thread的Node节点加入等待链表,暂存锁的重入值,release()释放锁,进入阻塞态,等待被唤醒,唤醒后,尝试走获锁流程。
  3. signal时,取出Node,移入阻塞链表,唤醒Node引用的Thread。
  1. 锁为啥要这样设计newCondition
    await 会阻塞当前线程、记录lock重入的次数,所以必须在lock块内执行。
    signal 根据node节点唤醒对应Thread,必须在获得锁的线程才能调用signal,signal会检测获取锁线程和 当前线程是否为一个线程,必须为一个线程,否则抛出异常,因为signal内部代码块无法保证事务,所以也必须在lock块内部。做了强制判断。
    protected final boolean isHeldExclusively() {
    // While we must in general read state before owner,
    // we don't need to do so to check if current thread is owner
    return getExclusiveOwnerThread() == Thread.currentThread();
    }
  1. 在BlockingQueue阻塞队列中,用了两个锁,putLock和takeLock,用了signal一个一个串行的唤醒,同时为了避免发生死锁。
上一篇下一篇

猜你喜欢

热点阅读