//Reentrant的其他方法:
//先看lockInterruptibly方法,该方法主要用于如果该线程未被中断则获取锁
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public final void acquireInterruptibly(int arg)
throws InterruptedException {
//如果当前线程已经被中断抛出异常
if (Thread.interrupted())
throw new InterruptedException();
//尝试获取锁
if (!tryAcquire(arg))
//没有获取到锁
doAcquireInterruptibly(arg);
}
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
//入队
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
//被中断抛出异常
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
/**
该方法和lock()方法大部分过程都相同最主要是新增了中断的判断。
刚开始尝试获得锁的时候判断当前线程是否已经被中断。
入队后,挂起当前线程的时候又会判断当前线程是否已经被中断。
两次判断。其余流程与lock()一致。
*/
//看tryLock方法,尝试获取锁成功返回true,失败返回false。
public boolean tryLock() {
return sync.nonfairTryAcquire(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;
}
/**该方法即尝试获取锁,获取成功返回true,失败返回false*/
//看trylock的重载方法
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
//如果线程被中断抛出异常
if (Thread.interrupted())
throw new InterruptedException();
//尝试获取锁
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
private boolean doAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
long lastTime = System.nanoTime();
//入队
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return true;
}
//超时了
if (nanosTimeout <= 0)
return false;
if (shouldParkAfterFailedAcquire(p, node) &&
//nanosTimeout>1秒才挂起.因为时间太短的话可能挂起的时间已经超过自旋的时间。
nanosTimeout > spinForTimeoutThreshold)
//挂起当前线程
LockSupport.parkNanos(this, nanosTimeout);
//计算时间
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
lastTime = now;
if (Thread.interrupted())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
/** 该方法时指在指定时间内获得锁*/
//getHoldCount()返回当前线程保持该锁的次数
public int getHoldCount() {
return sync.getHoldCount();
}
final int getHoldCount() {
//当前线程是独占线程
return isHeldExclusively() ? getState() : 0;
}
//返回是否是独占方式调用的线程
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
//isHeldByCurrentThread() 查询当前线程是否拥有此锁
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
//isLock()查询锁是否已经被拥有
public boolean isLocked() {
return sync.isLocked();
}
final boolean isLocked() {
return getState() != 0;
}
//isFair() 判断该锁是否为公平锁
public final boolean isFair() {
return sync instanceof FairSync;
}
//getOwner()返回拥有当前锁的线程
protected Thread getOwner() {
return sync.getOwner();
}
/**
这个方法有些奇怪为什么要判断getState不直接getExclusiveOwnerThread()?
因为 private volatile int state; state是volatile的,是安全的。
而 private transient Thread exclusiveOwnerThread。没有volatile关键字没有保证内存可见性。
*/
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//判断是否有线程队列在等待此锁
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
/**在线程入队的时候,如果队列为空,会初始化一个节点作为头节点和尾节点。
所以如果头结点和尾节点相等表示没有中间节点即队列为空。
*/
public final boolean hasQueuedThreads() {
return head != tail;
}
//查询给定线程是否在等待此锁
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
public final boolean isQueued(Thread thread) {
if (thread == null)
throw new NullPointerException();
//从队伍开始查找此线程
for (Node p = tail; p != null; p = p.prev)
if (p.thread == thread)
return true;
return false;
}
//getQueueLength()返回正在等待该锁的线程估计数
public final int getQueueLength() {
return sync.getQueueLength();
}
public final int getQueueLength() {
int n = 0;
//从队尾开始像前搜索
for (Node p = tail; p != null; p = p.prev) {
if (p.thread != null)
++n;
}
return n;
}
//getQueuedThreads()获取正在等待的所有线程封装到ArrayList中
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
public final Collection<Thread> getQueuedThreads() {
ArrayList<Thread> list = new ArrayList<Thread>();
//从队尾开始遍历所有节点
for (Node p = tail; p != null; p = p.prev) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
return list;
}
//查询是否有线程等待在该条件对上等待。
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public final boolean hasWaiters(ConditionObject condition) {
//判断该condition是否为当前sync所拥有
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.hasWaiters();
}
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
return sync == AbstractQueuedSynchronizer.this;
}
protected final boolean hasWaiters() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
//从头开始查找有没有waitStatus等于CONDITION的节点。有就说明有线程在该条件上等待
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
return true;
}
return false;
}
//获取当前condition等待线程上的预估数
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
protected final int getWaitQueueLength() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int n = 0;
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
++n;
}
return n;
}
//获取该condition上等待的线程封装到Collection中
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
protected final Collection<Thread> getWaitingThreads() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION) {
Thread t = w.thread;
if (t != null)
list.add(t);
}
}
return list;
}
分享到:
相关推荐
《TMS320F28x源码解读——深入理解数字信号处理器的精髓》 在数字信号处理领域,TMS320F28x系列芯片因其高性能、低功耗的特点,被广泛应用于各种复杂系统中,如工业自动化、电力控制、通信设备等。这些系统的核心...
HashMap 之 put 方法源码解读 HashMap 是 Java 中一种常用的数据结构,用于存储键值对。其中,put 方法是 HashMap 中最重要的方法之一,负责将键值对存储到HashMap 中。在本文中,我们将对 HashMap 的 put 方法的...
4500页的源码解读 光是SELECT语句相关实现,就阐述了300多页 看完了你就是postgreSQL达人了 章节明细,需要精读那个功能点就仔细看
Netty5.0架构剖析和源码解读 本文档主要讲述了Netty5.0架构剖析和源码解读,涵盖了Netty的架构、源码分析、NIO入门等方面的知识点。 概述 JAVA 的 IO 演进是一个长期的过程,从传统的 BIO 通信到 NIO 的出现,都...
源码解读是软件开发中的一项重要技能,它涉及到对程序源代码的深入理解和分析,以揭示系统的功能实现和设计思路。在《源码解读的基本原理》中,我们了解到源码解读能够帮助我们理解系统的运作机制,提升编程能力,并...
Spring框架的设计理念和实现方式对许多其他Java框架产生了深远影响,因此深入理解Spring源码对于提升整体编程技能至关重要。 Spring框架主要由以下几个模块组成: 1. **核心容器**:这是Spring的基石,包括...
Spark源码解读迷你 RDD、Spark Submit、Job、Runtime、Scheduler、Spark Storage、Shuffle、Standlone算法、Spark On yarn。。。
Netty5.0架构剖析和源码解读,旨在为读者提供深入理解Netty内部工作机制的途径,通过源码层面的分析帮助开发者更好地掌握Netty的应用和优化。 1. JAVA的IO演进 在Netty 5.0之前,Java IO主要经历了BIO到NIO的演进...
jQuery 源码解读 jQuery 是一款非常流行的 JavaScript 库,以其简洁的语法和强大的功能深受开发者喜爱。本文将深入探讨 jQuery 的源码结构和执行流程,帮助你更好地理解和运用这个库。 首先,jQuery 的核心架构是...
《Resin源码解读》 Resin,作为一个高性能的Java应用服务器,其源码解析对于我们深入理解Web服务器的运行机制和优化技术具有重要的价值。本文将从日志分析、运行时调试、网络模型以及线程池模型四个方面进行深入...
在源码解读方面,我们可以关注以下几个关键部分: 1. **BossGroup 和 WorkerGroup 的实现**:通常基于NIO的Selector实现,BossGroup负责监听新连接,而WorkerGroup处理已连接的SocketChannel。 2. **Channel 实现*...
在《PX4源码解读》中,我们可以深入探讨这个系统的核心组成部分和工作原理。首先,PX4的架构由几个关键模块组成: 1. **硬件抽象层**:这层代码确保了PX4可以适应各种硬件平台,包括不同类型的传感器、处理器和通信...
Spark-2.3.1源码解读。 Spark Core源码阅读 Spark Context 阅读要点 Spark的缓存,变量,shuffle数据等清理及机制 Spark-submit关于参数及部署模式的部分解析 GroupByKey VS ReduceByKey OrderedRDDFunctions...
VxWorks以其高效、确定性和微秒级的响应时间著称,它的源码解读对于我们理解其工作原理、优化系统性能以及进行定制化开发具有重要意义。 首先,我们要了解VxWorks的核心组成部分,包括内核(Kernel)、文件系统...
JEECMS2源码的解读,介绍JEECMS2源码的结构,开发流程等
综上所述,“Pixhawk源码总结.pdf”这份文档详细介绍了Pixhawk的软件架构、关键算法以及源码解读,对于想要深入学习开源飞控系统的人来说,是一份宝贵的参考资料。通过阅读和实践,开发者可以更好地掌握无人机飞行...
本文将针对"Vue进阶面试题,源码解读,含Vue3源码解读"这一主题,详细探讨相关知识点。 首先,对于Vue进阶面试题,通常会涉及到以下几个方面: 1. **响应式原理**:Vue基于ES6的Proxy和Reflect实现数据的响应式,...
@RequestMapping注解用于映射Web请求到相应的处理方法上。 总而言之,通过对Spring Boot源码的解析,可以了解到Spring Boot是如何简化Spring应用的配置和部署的,其中涉及到的自动装配、条件装配和自定义启动器等...
这篇博文“Struts2源码解读”深入剖析了Struts2的核心机制,帮助开发者更好地理解和利用这个框架。源码分析是提升编程技能和解决问题的关键,特别是对于复杂的框架如Struts2,理解其内部工作原理能够帮助我们优化...