AQS

本文深入解析了AQS(AbstractQueuedSynchronizer)框架,介绍了其作为Java并发工具包中核心组件的作用,包括ReentrantLock、Semaphore等同步类的实现原理。通过自定义ReentrantLock和Semaphore的实例,详细展示了AQS的使用方式和内部机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是AQS

AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的。

AQS使用方式和其中的设计模式

继承,模板方法设计模式

独占式锁代表:ReentrantLock

共享式锁代表:ReadLock

模板方法:

独占式获取

accquire

acquireInterruptibly

tryAcquireNanos

共享式获取

acquireShared

acquireSharedInterruptibly

tryAcquireSharedNanos

独占式释放锁

release

共享式释放锁

releaseShared

需要子类覆盖的流程方法

独占式获取  tryAcquire

独占式释放  tryRelease

共享式获取 tryAcquireShared

共享式释放  tryReleaseShared

这个同步器是否处于独占模式  isHeldExclusively

同步状态state:

getState:获取当前的同步状态

setState:设置当前同步状态

compareAndSetState 使用CAS设置状态,保证状态设置的原子性

 LockSupport

主要用于将一个线程设置为阻塞状态,或者唤醒线程

 

pack 阻塞

unpack 唤醒                                                                                                                                                                               

独占式流程

 

 自实现ReentrantLock

public class MyReentrantLock implements Lock {
    //state 表示获取到锁 state=1 获取到了锁,state=0,表示这个锁当前没有线程拿到
    private static class Sync extends AbstractQueuedSynchronizer {
        //是否处于独占模式
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        //尝试获取锁
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                //设置当前线程为锁拥有者
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        //尝试释放该锁
        @Override
        protected boolean tryRelease(int arg) {
            if(getState() == 0){//当前状态为未持有锁状态,则直接抛错
                throw new UnsupportedOperationException();
            }
            //设置锁的持有者为null
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        private Condition newCondition(){
            return new ConditionObject();
        }
    }

    static Sync sync = new Sync();

    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }
}
public class AQSTest {
    static Lock lock = new MyReentrantLock();

    static class MyThread extends Thread {
        @Override
        public void run() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " start to do work");
                Thread.sleep(5);
                System.out.println(Thread.currentThread().getName() + " work done");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new MyThread().start();
        }
    }
}

运行结果:

Thread-0 start to do work
Thread-0 work done
Thread-4 start to do work
Thread-4 work done
Thread-2 start to do work
Thread-2 work done
Thread-1 start to do work
Thread-1 work done
Thread-3 start to do work
Thread-3 work done

根据结果显示,独占锁生效。

自实现Semaphore

原理:设置共享锁,设定同时最多可以有几个线程获取该锁

public class MySemaphore implements Lock {
    Sync sync = new Sync(3);

    static class Sync extends AbstractQueuedSynchronizer {
        //设置AbstractQueuedSynchronizer的state的个数,根据对state的数量的判断,来实现同时最多几个线程获取锁
        Sync(int count) {
            if (count < 0) {
                throw new IllegalArgumentException("count must large than zero.");
            }
            setState(count);
        }

        //共享锁子类需要重写的方法
        @Override
        protected int tryAcquireShared(int reduceCount) {
            for (;;) {
                int current = getState();
                int newCount = current - reduceCount;
                if (newCount < 0 || compareAndSetState(current, newCount)) {
                    return newCount;
                }
            }
        }

        //共享锁子类需要重写的方法
        @Override
        protected boolean tryReleaseShared(int returnCount) {
            for (;;) {
                int current = getState();
                int newCount = current + returnCount;
                if (compareAndSetState(current, newCount)) {
                    return true;
                }
            }
        }

        Condition newCondition() {
            return new ConditionObject();
        }

    }

    @Override
    public void lock() {
        sync.acquireShared(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquireShared(1) >= 0;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.releaseShared(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }
}

public class MySemaphoreTest {
    static MySemaphore semaphore = new MySemaphore();

    static class MyThread extends Thread {
        @Override
        public void run() {
            semaphore.lock();
            try {
                System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis());
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.unlock();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new MyThread().start();
        }
    }
}

运行结果:

Thread-0:1590145302725
Thread-2:1590145302725
Thread-1:1590145302725
Thread-4:1590145304725
Thread-5:1590145304725
Thread-6:1590145304726
Thread-3:1590145306725
Thread-8:1590145306725
Thread-9:1590145306726
Thread-7:1590145308725

 

<think>好的,用户的问题是关于AQS的。首先需要明确用户的具体需求是什么。AQS可能指多个领域,比如Java中的AbstractQueuedSynchronizer,或者空气质量系统(Air Quality System),还有可能涉及其他缩写。根据常见的编程问题,推测用户可能是在询问Java并发框架中的AQS。 接下来要调用网络搜索工具,查找AQS的相关信息。主要关注Java中的AbstractQueuedSynchronizer,确认其作用、原理、使用场景等。同时需要整理搜索结果,确保信息的准确性和实用性。 在整合信息时,需要将AQS的基本概念、核心机制、应用场景分点说明,避免使用步骤词汇,保持每个部分独立。同时注意代码和公式的格式要求,确保正确使用行内公式和代码块。 需要检查是否遗漏其他可能的AQS含义,比如空气质量系统,但根据编程上下文,优先处理Java相关的解释。如果搜索结果中有其他含义,可能需要简要提及,但重点放在Java部分。 最后生成相关问题部分,需基于用户的问题和回答内容,提出三个相关的问题,比如实现原理、使用场景、与其他锁的关系等。确保问题符合格式要求,使用正确的标题和编号。</think>AQS(AbstractQueuedSynchronizer)是Java并发包中构建锁和同步器的核心框架,采用CLH队列变体实现线程阻塞管理。其核心机制基于**state**状态变量和**FIFO双向队列**实现资源获取/释放的线程调度。 **核心原理** - **状态管理**:通过volatile修饰的int类型`state`字段表示资源状态,子类通过`getState()`/`setState()`/`compareAndSetState()`进行原子操作。例如`ReentrantLock`用state=0表示未锁定,state>0表示锁定次数 - **队列节点**:队列节点包含`waitStatus`字段,包含以下状态: - `CANCELLED(1)`:线程已取消 - `SIGNAL(-1)`:后继节点需要唤醒 - `CONDITION(-2)`:处于条件等待队列 - `PROPAGATE(-3)`:共享模式下需要传播唤醒 **实现模式** ```java // 自定义同步器模板 class CustomSync extends AbstractQueuedSynchronizer { protected boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } return false; } } ``` **典型应用** - `ReentrantLock`:可重入排他锁 - `Semaphore`:信号量控制 - `CountDownLatch`:倒计时门闩 - `ReentrantReadWriteLock`:读写锁分离 **资源获取公式** $$资源状态 = \begin{cases} 0 & \text{可用状态} \\ n & \text{被占用状态(n表示重入次数/资源数量)} \end{cases}$$ **锁公平性实现** 公平锁通过`hasQueuedPredecessors()`方法检查队列中是否存在等待时间更长的线程,非公平锁直接尝试CAS抢锁: ```java final void lock() { if (compareAndSetState(0, 1)) // 非公平锁直接尝试抢锁 setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值