Java中的AQS(三)线程的阻塞和唤醒

本文详细介绍了Java中的AQS(AbstractQueuedSynchronizer)中线程如何被阻塞和唤醒。当线程获取同步状态失败,会加入同步队列并自旋尝试。线程是否需要阻塞由shouldParkAfterFailedAcquire方法判断,返回true则调用parkAndCheckInterrupt方法阻塞线程。释放同步状态后,unparkSuccessor方法用于唤醒后续节点的线程。整个过程涉及到了LockSupport的park和unpark方法,这些是线程阻塞和唤醒的基础原语。
摘要由CSDN通过智能技术生成

一、线程的阻塞:    

    在上一篇说到,线程获取同步状态失败的线程,会构造节点并加入到同步队列的尾部,然后通过自旋的方式不断的获取同步状态,但是在自旋过程中需要判断线程是否需要阻塞,我们再一次看一下acquire方法。

final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            //也就是在这里需要判断线程是否需要阻塞
            if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                interrupted = true;
        }

首先打开shouldParkAfterFailedAcquire方法

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    //前驱节点的等待状态
    </
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: AQS (AbstractQueuedSynchronizer) 是 Java 的一种用于实现同步器的抽象类。它提供了一种通用的机制,用于实现同步工具(如锁、信号量和闭锁),而不需要编写底层同步代码。AQS 实现了一个队列,用于在多个线程之间安全地传递同步状态。 ### 回答2: AQS(AbstractQueuedSynchronizer,即抽象队列同步器)是Java用于实现同步机制的基础类。它提供了一种在同步状态下等待/通知的机制,并支持独占和共享两种同步方式。 AQS基于一个先进先出(FIFO)的双向队列,被称为等待队列,来存储等待获取同步状态的线程。每个线程在申请获取同步状态时会被加入到等待队列的尾部,同时被阻塞。当同步状态可用时,只有队列头部的线程才能获取到同步状态,并被唤醒继续执行。 AQS采用了模板方法设计模式,提供了独占模式下的acquire和release方法以及共享模式下的acquireShared和releaseShared方法。具体的同步实现逻辑由子类来实现。 在AQS,同步状态(state)是通过一个int类型的变量来表示,而具体的同步语义由子类的实现方法来定义。AQS利用CAS(Compare and Swap)操作来保证同步状态的原子操作,这也是保证AQS实现的线程安全性的基础。 除了同步的基本功能,AQS还提供了一些扩展方法,如条件队列的支持,子类可以通过实现Condition接口来创建自己的条件队列。 总之,AQSJava基于队列的同步控制机制的基础类,它通过一种等待/通知的机制实现线程间的同步和通信,提供了独占模式和共享模式的支持,是Java并发编程非常重要的一个类。 ### 回答3: AQS (AbstractQueuedSynchronizer) 是 Java 用于构建同步器的基础框架。它提供了一套简单且灵活的实现方式,可用于构建各种类型的同步器,如锁、信号量、倒计时门栓等。 AQS 的核心是一个等待队列,用于管理等待获取同步状态的线程。它通过内部的 node 对象来表示每个线程,并使用 CAS 操作来实现线程的安全操作。当一个线程需要获取同步状态时,它会在等待队列插入一个 node,并进入自旋或阻塞等待其他线程唤醒。当某个线程释放同步状态时,AQS 会将状态转移给队列的下一个等待线程AQS 为具体的同步器提供了两种操作:获取同步状态和释放同步状态。获取同步状态的方式一般有两种:独占方式 (Exclusive) 和共享方式 (Shared)。独占方式是指同一时间只能有一个线程获取同步状态,如 ReentrantLock;共享方式是指多个线程可以同时获取同步状态,如 CountDownLatch。 AQS 的实现基于模板方法设计模式,使用了一个 state 成员变量来表示同步状态。具体的同步器需要继承并实现 AQS 的抽象方法,包括获取同步状态的方法 (tryAcquire、tryAcquireShared) 和释放同步状态的方法 (tryRelease、tryReleaseShared)。通过重写这些方法,可以定制实现特定的同步逻辑。 总而言之,AQSJava 用于构建同步器的基础框架,通过等待队列和内部的 node 对象来管理线程的获取和释放同步状态。它提供了一套简单且灵活的实现方式,并支持独占和共享两种同步方式。通过继承并实现 AQS 的抽象方法,可以定制实现各种类型的同步器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值