美文网首页
Java 共享锁 Condition实现

Java 共享锁 Condition实现

作者: 攻城狮托马斯 | 来源:发表于2020-05-16 11:36 被阅读0次

    共享锁AQS中的实现


    共享锁在AQS中实现非常简单.

    当独占锁的Node取得锁后,便结束了, 而一旦共享锁的node取得锁,便会一直向下propagate传递, 把后面排队的线程全部唤醒, 直到当前的state变成0为止. 这和重入锁的原理有些类似.

    并且, tryaquire()和tryrelease()此时会改成tryacuireShared()和tryreleaseShared(), 在之前的CAS基础上对state的状态, 从3 到 2 到1 到 0.

    Condition的实现


    和之前的CLH队列类似, 只是队列拥有多个condition在等待, 每一个状态拥有一个condition

    await(): 把当前节点加入到condition队列的尾部, 让Node进入所谓的park状态

    signal():唤醒condition下面的第一个node, 让这个node重新进行入队addWaiter();

    signal() vs.signalAll()


    之前在notify()和notifyAll()中, 尽量使用notifyAll()是因为可能有多个参数发生改变 (ex.车里程数或油耗改变, 通知系统)

    而因为显示锁可以拥有多个condition, 比如说, mileCondition, oilCondition, 因此在condition中的signal()方法只需要signal()一个就可以.

    signalAll(): signalAll()的使用在于当一个任务结束,需要唤醒一个Condition队列下的多个线程去做很多不同的时期,这时候用signalAll(), 当然signalAll()只用于一个condition队列下的所有等待的node.

    重入锁的实现


    在tryAcquire中,检查是否是当前线程已拿锁,然后用CAS对CompareAndSetState做出改变

    公平锁的实现


    在tryAcuiqre()中,公平锁会先看一看CLH队列中有没有node, 如果没有的话直接加入, 否则就尝试addWaiter()去尾部

    重入锁中的读锁和写锁


    如图, 分别有一个读锁和一个写锁. 在读锁中, 和写锁进行互斥。在写锁中, 和读锁还有其他写锁进行互斥, 那么是如何实现的呢?

    首先, readLock()和writeLock()中共享一个int state,然后这个int的前16位是读锁,后16位是写锁. 

    然后给了写锁一个threadLocal()来记录可重入问题。

    相关文章

      网友评论

          本文标题:Java 共享锁 Condition实现

          本文链接:https://www.haomeiwen.com/subject/yilcohtx.html