/** 将结点插入队列,如果队列为空,初始化队列,否则将结点入队列 **/ private Node enq(final Node node) { for (;;) { Node t = tail; if (t == null) { // 尾结点为null时初始化 Node h = new Node(); h.next = node; node.prev = h; if (compareAndSetHead(h)) { //1比较并更新头结点 tail = node; //如果这一行CPU切换了线程,其它线程同样执行插入节点操作时,会在1处执行失败, return h; //直到第一次执行插入节点操作的线程恢复运行时尾结点才会更新成功 } } else { node.prev = t; //如果队列不为空,让新结点的前一节点指向尾结点 if (compareAndSetTail(t, node)) { t.next = node; return t; } } } } /** 创建和入队节点给定线程和模式 **/ private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // 尝试将新结点插入队列,失败则进入enq函数(循环尝试) Node pred = tail; if (pred != null) { node.prev = pred; if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } enq(node); return node; } /** 唤醒给定结点的继任节点 **/ private void unparkSuccessor(Node node) { //修改结点的waitStatus状态,成功失败都OK,失败说明有线程已修改完状态 //成功也说明节目的状态已被修改 compareAndSetWaitStatus(node, Node.SIGNAL, 0); //继任结点是null or 继任结点被取消时,从队尾寻找真实继任结点 Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } if (s != null) LockSupport.unpark(s.thread); } /** 未理解此方法 **/ private void setHeadAndPropagate(Node node, int propagate) { setHead(node); if (propagate > 0 && node.waitStatus != 0) { Node s = node.next; if (s == null || s.isShared()) unparkSuccessor(node); } } /** 检查并更新获取失败节点的状态 **/ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int s = pred.waitStatus; if (s < 0) //表明此节点的继任节点需求释放,可以安全park return true; if (s > 0) { //表明前任节点被取消,继续向前循环 do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else //表明需要一个signal,但不能park,调用者进行循环重试,确保park以前不能获取锁 compareAndSetWaitStatus(pred, 0, Node.SIGNAL); return false; } // Condition内部类 /** 检查中断,如果被唤醒之前中断抛异常,如果唤醒之后中断重新中断,否则返回0 **/ private int checkInterruptWhileWaiting(Node node) { return (Thread.interrupted()) ? ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) : 0; } /** 如果一个结点最初被放置在等待队列,现在在同步队列等待重新获取锁,返回true。 **/ final boolean isOnSyncQueue(Node node) { //条件队列初始化时,prev节点为空,此条件说明此节点还在条件队列 if (node.waitStatus == Node.CONDITION || node.prev == null) return false; if (node.next != null) // If has successor, it must be on queue return true; return findNodeFromTail(node); } 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) unlinkCancelledWaiters(); //处理中断 if (interruptMode != 0) reportInterruptAfterWait(interruptMode); }
相关推荐
在Java并发编程中,`AbstractQueuedSynchronizer`(AQS)是一个重要的抽象类,用于构建锁和其他同步组件。AQS的核心是通过一个整型变量`state`来表示同步状态,并利用双端队列(FIFO)管理等待的线程。在本篇中,我们...
framework based on class AbstractQueuedSynchronizer. This framework provides common mechanics for atomically managing synchronization state, blocking and unblocking threads, and queuing. The paper ...
这是 jdk 6u11 的jre 解压以后得到的 rt.jar, 将rt.jar 解压获得了 AbstractQueuedSynchronizer.class 文件
这是 jdk 6u11 的jre 解压以后得到的 rt.jar, 将rt.jar 解压获得了 AbstractQueuedSynchronizer.Node.class 文件
**Java并发系列之AbstractQueuedSynchronizer源码分析概要** **1. AbstractQueuedSynchronizer(AQS)的定义与作用** AbstractQueuedSynchronizer(AQS)是Java并发编程中的核心组件,它是一个抽象的、基于FIFO...
【Java并发系列之AbstractQueuedSynchronizer源码分析(独占模式)】 AbstractQueuedSynchronizer(AQS)是Java并发编程中一个重要的工具,它是Java并发包`java.util.concurrent.locks`中的核心抽象类,用于构建锁...
AbstractQueuedSynchronizer.java
Java锁之AbstractQueuedSynchronizer,队列同步器实现锁或其它相关同步类的基础类
ReentrantLock Lock 加锁过程源码分析图,AQS 源码分析
Java同步框架AbstractQueuedSynchronizer详解 AbstractQueuedSynchronizer(AQS)是Java中的一个同步框架类,它实现了最核心的多线程同步的语义。AQS提供了一个基础的同步器实现,开发者可以通过继承AQS来实现自己...
《Java并发系列之AbstractQueuedSynchronizer源码分析(共享模式)》 AbstractQueuedSynchronizer(AQS)是Java并发编程中一个重要的工具,它是Java并发包`java.util.concurrent.locks`中的核心抽象类,用于构建锁...
《Chinese_AQS:为中国程序员解析AbstractQueuedSynchronizer》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)是一个至关重要的组件,它为实现锁和其他同步构建块提供了基础。然而,由于其复杂性和原始...
并以java锁机制实现基类AbstractQueuedSynchronizer的实现为例,从类(核心属性、方法)设计思路,到对关键代码做注释分析,再到以流程图方式直观解释流程;最后介绍了AbstractQueuedSynchronizer的应用,即如何用它...
为了支持阻塞和唤醒操作,`AbstractQueuedSynchronizer`使用了AQS(AbstractQueuedSynchronizer)队列。当一个线程尝试获取同步状态但失败时,会被插入到AQS队列中并被阻塞;当其他线程释放了同步状态时,队列中的...
本文将深入探讨这些机制的底层实现,特别是通过`AbstractQueuedSynchronizer`(AQS)来理解`ReentrantLock`和`CountDownLatch`的工作原理。 首先,`ReentrantLock`是一个可重入互斥锁,允许同一个线程多次获取锁,...
8.初识Lock与AbstractQueuedSynchronizer(AQS) 9.深入理解AbstractQueuedSynchronizer(AQS) 10.彻底理解ReentrantLock 11.深入理解读写锁ReentrantReadWriteLock 12.详解Condition的await和signal等待通知机制 13....
本资源摘要信息涵盖了 Java 后端开发的多个方面,包括 JPA 防踩坑姿势、Servlet 3 异步原理与实践、Tomcat 源码剖析、Java 并发编程、Java 线程池、AbstractQueuedSynchronizer、Tomcat 系列、Netty 系列、Kafka ...
在上述代码中,`Sync` 类继承了 `AbstractQueuedSynchronizer`,`setState()` 初始化了 `state` 的值,`tryAcquireShared()` 和 `tryReleaseShared()` 分别用于获取和释放同步状态(即减少计数器)。 总之,...
4. **同步器(Synchronizers)**:JUC库中的同步器主要是通过AQS(AbstractQueuedSynchronizer)来实现的。AQS是一个抽象类,为锁和同步器提供了一种通用的底层实现。它维护了一个等待队列,提供了基于FIFO的等待...