【JDK1.8】JUC——AbstractQueuedSynchronizer

在上一篇中,我们对LockSupport进行了阅读,因为它是实现我们今天要分析的AbstractQueuedSynchronizer(简称AQS)的基础,重新用一下最开始的图:

juc

可以看到,在ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock中都用到了继承自AQS的Sync内部类,正如AQS的java doc中一开始描述:

Provides a framework for implementing blocking locks and related synchronizers (semaphores, events, etc) that rely on first-in-first-out (FIFO) wait queues.

为实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量,事件等)提供框架。

AQS根据模式的不同:独占(EXCLUSIVE)和共享(SHARED)模式。

独占:只有一个线程能执行。如ReentrantLock。

共享:多个线程可同时执行。如Semaphore,可以设置指定数量的线程共享资源。

对应的类根据不同的模式,来实现对应的方法。


二、结构概览

试想一下锁的应用场景,当线程试图请求资源的时候,先调用lock,如果获得锁,则得以继续执行,而没有获得,则排队阻塞,直到锁被其他线程释放,听起来就像是一个列队的结构。而实际上AQS底层就是一个先进先出的等待队列

【JDK1.8】JUC——AbstractQueuedSynchronizer

队列采用了链表的结构,node作为基本结构,主要有以下几个成员变量:

static final class Node { //用来表明当前节点的等待状态,主要有下面几个: // CANCELLED: 1, 表示当前的线程被取消 // SIGNAL: -1, 表示后继节点需要运行,也就是unpark // CONDITION: -2, 表示线程在等待condition // PROPAGATE: -3, 表示后续的acquireShared能够得以执行,在共享模式中用到,后面会说 // 0, 初始状态,在队列中等待 volatile int waitStatus; // 指向前一个node volatile Node prev; // 指向后一个node volatile Node next; // 指向等待的那个线程 volatile Thread thread; // 在condition中用到 Node nextWaiter; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssdyd.html