Java同步器AQS架构AbstractQueuedSynchronizer原理解析
什么是AQS?
抽象队列同步器(AbstractQueuedSynchronizer,AQS)是Java中一种同步工具,它是构建锁与同步器的框架,是并发包中用来构造锁、信号量、倒计数器、线程池等等使用的开发工具类。它采用了一种FIFO的队列等待机制来保证线程执行的顺序。
AQS的核心思想
AQS的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是通过内部的FIFO队列来实现的。
AQS的核心组成
在AQS中,派生类需要实现以下方法:
- isHeldExclusively()
- tryAcquire(int)
- tryRelease(int)
其中isHeldExclusively()
方法判断当前线程是否保持独占模式,只有用到 ReentrantLock
中的 Condition 才需要这个功能。
tryAcquire(int)
方法是独占模式下的资源申请。在独占模式下,当拿不到这把锁的时候会将当前线程唤醒,添加到队列中。
tryRelease(int)
方法是独占模式下的释放资源。
如何使用AQS
以 ReentrantLock
为例,演示如何使用AQS。
示例1:简单的 ReentrantLock 使用示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
private static Lock lock = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
public void run() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "获得了锁");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "释放了锁");
lock.unlock();
}
}
}).start();
}
}
}
示例代码中,我们定义了一个 ReentrantLock
对象,然后在一个 for 循环中创建了5个线程,每个线程获取锁、睡眠 500 毫秒进入阻塞状态,然后释放锁。
示例2:Lock 结合 Condition 示例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockConditionDemo {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "等待信号");
condition.await();
System.out.println(Thread.currentThread().getName() + "收到信号");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
lock.lock();
System.out.println(Thread.currentThread().getName() + "发出信号通知");
condition.signalAll();
lock.unlock();
}
}).start();
}
}
示例代码中,我们定义了一个 ReentrantLock
对象以及一个 Condition
对象,生产者线程发出一个信号通知,然后唤醒等待信号的消费者线程,消费者线程接收到要求后,执行最后的代码逻辑。
总结
通过上面的例子,我们初步了解到了什么是AQS,其核心思想和组成部分,以及如何使用 ReentrantLock
和 Condition
针对 AQS 进行对锁与同步器进行控制的实现方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java同步器AQS架构AbstractQueuedSynchronizer原理解析 - Python技术站