可重入锁 ReentrantLock
来源:互联网 发布:双翼软件官网 编辑:程序博客网 时间:2024/06/05 15:47
公平锁和非公平锁
公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
源码
// 公平锁和非公平锁 public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
非公平锁是: 先state+1,然后直接得到锁,
而公平锁则是: 先尝试去获取锁,如果得到了锁则state+1.
// 非公平锁 final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } // 公平锁 protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // 检测等待队列是否为空或者等待队列头元素是不是当前线程 // 没轮到当前线程不能被唤醒 if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } // 检测等待队列是否为空或者等待队列头元素是不是当前线程 public final boolean hasQueuedPredecessors() { Node t = tail; Node h = head; Node s; return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); }
其中Thread和各种节点都是volatile ,保证了可见性
volatile Thread thread;
Condition
public class ConditionObject implements Condition, java.io.Serializable { // 等待condition的队列,双向链表 private transient Node firstWaiter; private transient Node lastWaiter; // 唤醒第一个线程 public final void signal() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignal(first); } // 等待 public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); int interruptMode = 0; while (!isOnSyncQueue(node)) { LockSupport.park(this); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); } // 加入等待队列尾端 private Node addConditionWaiter() { Node t = lastWaiter; // If lastWaiter is cancelled, clean out. if (t != null && t.waitStatus != Node.CONDITION) { unlinkCancelledWaiters(); t = lastWaiter; } Node node = new Node(Thread.currentThread(), Node.CONDITION); if (t == null) firstWaiter = node; else t.nextWaiter = node; lastWaiter = node; return node; } }
0 0
- 可重入锁 ReentrantLock
- ReentrantLock可重入锁
- ReentrantLock可重入锁
- ReentrantLock(可重入锁)
- 可重入锁 ReentrantLock
- ReentrantLock可重入锁
- 可重入锁 -- ReentrantLock
- ReentrantLock可重入锁
- 码农小汪-ReentrantLock 可重入锁
- java可重入锁ReentrantLock原理
- 可重入锁(ReentrantLock)
- 可重入锁ReentrantLock初探
- ReentrantLock可重入锁简介
- ReentrantLock
- ReentrantLock
- ReentrantLock
- ReentrantLock
- ReentrantLock
- MongoDB 3.0+ 安全权限访问控制
- InitCommonControls()
- openwrt上如何进行串口加密
- 自动获取短信验证码并填充以及倒计时
- 38. Count and Say
- 可重入锁 ReentrantLock
- html三大分类
- 公钥、私钥、数字证书_解释
- Shell输入输出重定向:Shell Here Document,/dev/null文件
- Session的生命周期
- Broadcast middleware common flow
- 防止SQL注入解决办法
- Toast实现图文混排
- Palindrome Number leetcode