CLH Lock & MCS Lock
来源:互联网 发布:优化一个关键词多少钱 编辑:程序博客网 时间:2024/06/13 08:50
共性: 都是公平锁,先进先出,通过自旋轮询状态
区别: CLH锁持有前个节点状态并轮询,MCS持有后一个节点状态并轮询。
0,节点类 QNode
package com.test.learn;public class LockNode { /** * 标志锁的状态 */ volatile boolean locked = false; /** * 用于保存后个节点 */ volatile LockNode next = null;}
1,CLHLock
package com.test.learn;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicReference;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;public class CLHLock implements Lock { // 提供CAS方式修改地址引用 private AtomicReference<LockNode> tail; // 保存前一个节点引用 private ThreadLocal<LockNode> myPre; // 当前节点 private ThreadLocal<LockNode> myNode; public CLHLock() { tail = new AtomicReference<>(new LockNode()); myNode = ThreadLocal.withInitial(LockNode::new); myPre = ThreadLocal.withInitial(() -> null); } @Override public void lock() { // L1.将自身节点状态标志为true(已上锁) LockNode node = myNode.get(); node.locked = true; // L2.获取前个节点 LockNode pre = tail.getAndSet(node); myPre.set(pre); while (pre.locked) { // L3.自旋等待前个节点释放锁,即前一个节点执行unLock(U2处) } } @Override public void unlock() { // 获取当前节点 LockNode qnode = myNode.get(); // 通过状态标志为锁已释放 qnode.locked = false; // 回收前驱节点 myNode.set(myPre.get()); } @Override public void lockInterruptibly() throws InterruptedException { // TODO } @Override public boolean tryLock() { // TODO return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { // TODO return false; } @Override public Condition newCondition() { // TODO return null; }}
2,MCSLock
package com.test.learn;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicReference;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;public class MCSLock implements Lock { // 提供CAS方式修改地址引用 private AtomicReference<LockNode> tail; // 保存当前节点 private ThreadLocal<LockNode> myNode; public MCSLock() { // tail和CLH有区别,初始值为null tail = new AtomicReference<>(); myNode = ThreadLocal.withInitial(LockNode::new); } @Override public void lock() { LockNode qnode = myNode.get(); // L1,获取前节点 LockNode pre = tail.getAndSet(qnode); // L2.不存在前一个节点则直接获取锁了,否则自旋前节点的状态 if (null != pre) { qnode.locked = true; // L3 设置后续节点 pre.next = qnode; while (qnode.locked) { // 自旋前节点的状态 } } } @Override public void unlock() { LockNode qnode = myNode.get(); if (qnode.next == null) { // 为什么需要CAS判断是否更新成功?因为多线程下可能新增了新的节点。 if (tail.compareAndSet(qnode, null)) { return; } // 循环到等到next有值后退出,也即后一个节点执行L3之后 while (qnode.next == null) { } } // 解锁时候主动更新后节点状态(和CLH的主要差距点) qnode.next.locked = false; qnode.next = null; } @Override public void lockInterruptibly() throws InterruptedException { // TODO } @Override public boolean tryLock() { // TODO return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { // TODO return false; } @Override public Condition newCondition() { // TODO return null; }}
3, 使用
package com.test.learn;import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.locks.Lock;public class LockMain { private static final int THEAD_CNT = 10; private static Lock getLock() { // return new MCSLock(); return new CLHLock(); } public static void main(String[] args) throws Exception { CyclicBarrier cb = new CyclicBarrier(THEAD_CNT); CountDownLatch latch = new CountDownLatch(THEAD_CNT); Lock lock = getLock(); for (int i = 0; i < THEAD_CNT; i++) { Thread th = new Thread(() -> { try { cb.await(); System.out.println(Thread.currentThread().getName()); lock.lock(); System.out.println(Thread.currentThread().getName() + " Got the Lock!"); Thread.sleep(100); lock.unlock(); System.out.println(Thread.currentThread().getName() + " Released the Lock!"); latch.countDown(); } catch (Exception e) { e.printStackTrace(); } }, "Thread:" + i); th.start(); } long start = System.currentTimeMillis(); latch.await(); System.out.println("Duration:" + (System.currentTimeMillis() - start)); }}
阅读全文
1 0
- CLH Lock & MCS Lock
- Spin Lock -- CLH
- 线程锁系列(1):CLH Lock
- LOCK
- LOCK
- lock
- lock
- Lock
- Lock()
- lock
- LOCK
- Lock
- Lock
- Lock
- lock
- lock
- Lock
- Lock
- 算法竞赛入门——字母重排
- 虚拟机内的锁优化(偏向锁,轻量级锁,自旋锁,重量级锁)
- HDU
- 安装JDK之后,java -version正常,javac -version javac不是内部或外部命令。
- AngularJs学习之路(一)
- CLH Lock & MCS Lock
- Object.assign函数
- Redis
- 树的子结构
- PHP call_user_func_array ,call_user_func_array
- HDU6097Mindis(圆反演点)
- 推送安卓项目到码云
- 解决 mysql 插入反斜杠消失的问题
- [转帖]一致性Hash