AQS功能及源码详解

1.简介

AQS(AbstractQueuedSynchronizer)本身是一个抽象类,主要的使用方法是继承它作为一个内部类,JDK中许多并发工具类的内部实现都依赖于AQS,如ReentrantLock, Semaphore, CountDownLatch等等。

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer
    implements java.io.Serializable

2.实现思路:

AQS的实现依赖内部的同步队列(FIFO双向队列),线程首先会尝试获取锁,如果失败,则将当前线程以及等待状态等信息包成一个node节点加到同步队列尾部,接着会不断循环尝试获取锁(条件是当前节点为head的直接后继才会尝试),如果失败则会阻塞自己,直至被唤醒;而当持有锁的线程释放锁时,会唤醒队列中的后继线程。

2.1 主要作用:

1.同步状态的管理
2.线程的阻塞和唤醒
3.同步队列的维护

2.2 锁的获取

调用内部类的sync.acquire(1)方法,该方法会调用tryacquire()方法来试着获取独占锁,一般该方法需要重写

	@Override
    public void lock() {
   
        sync.acquire(1);
	}
 		@Override
        protected boolean tryAcquire(int arg){
   
            assert arg == 1;
            System.out.println("111");
            //原子设置当前状态
            if(compareAndSetState(0,1)){
    //原子操作
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

2.3 锁的释放

调用release()方法,该方法再调用tryRelease()方法。

3 API简介

  • int getState(): 获取同步状态
  • void setState(): 设置同步状态
  • boolean compareAndSetState(int expect, int update):基于CAS,原子设置当前状态
    自定义同步工具的话,一般都会基于覆盖以下几个方法来实现同步状态的管理
方法 描述
boolean tryAcquire(int arg) 试获取独占锁
boolean tryRelease(int arg) 试释放独占锁
int tryAcquireShared(int arg) 试获取共享锁
boolean tryReleaseShared(int arg) 试释放共享锁
boolean isHeldExclusively() 当前线程是否获得了独占锁

内嵌Node的定义

static final class Node {
   

    /**
     * 用于标记一个节点在共享模式下等待
     */
    static final Node SHARED = new Node();

    /**
     * 用于标记一个节点在独占模式下等待
     */
    static final Node EXCLUSIVE = null;

    /**
     * 等待状态:取消
     */
    static final int CANCELLED = 1;

    /**
     * 等待状态:通知
     */
    static final int SIGNAL = -1;

    /**
     * 等待状态:条件等待
     */
    static final int CONDITION = -2;

    /**
     * 等待状态:传播
     */
    static final int PROPAGATE = -3;

    /**
     * 等待状态
     */
    volatile int waitStatus;

    /**
     * 前驱节点
     */
    volatile Node prev;

    /**
     * 后继节点
     */
    volatile Node next;

    /**
     * 节点对应的线程
     */
    volatile Thread thread;

    /**
     * 等待队列中的后继节点
     */
    Node nextWaiter;

    /**
     * 当前节点是否处于共享模式等待
     */
    final boolean isShared() {
   
        return nextWaiter == SHARED;
    }

    /**
     * 获取前驱节点,如果为空的话抛出空指针异常
     */
    final Node predecessor() throws NullPointerException {
   
        Node p = prev;
        if (p == null) {
   
            throw new NullPointerException();
        } else {
   
            return p;
        }
    }

    Node() {
   
    }

    /**
     * addWaiter会调用此构造函数
     */
    Node(Thread thread, Node mode) {
   
        this.nextWaiter = mode;
        this.thread = thread;
    }

    /**
     * Condition会用到此构造函数
     */
    Node(Thread thread, int waitStatus
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值