AQS(AbstractQueuedSynchronizer)是Java并发编程中的一个重要工具类,用于构建锁和其他同步组件。AQS通过一个int类型的状态变量来表示同步状态,并维护一个FIFO的双向队列来管理等待线程。下面是一个简单的AQS并发编程示例,展示如何实现一个独占锁:
```java
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
// 简易版AQS,起名叫MyAQS
class MyAQS extends AbstractQueuedSynchronizer {
// 尝试获取资源
@Override
protected boolean tryAcquire(int arg) {
int state = getState();
if (state == 0 && compareAndSetState(0, arg)) {
// 如果当前宝藏没人拿(state为0),而且我能原子操作把状态改成“被占”(arg)
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 释放资源
protected void release(int arg) {
int state = getState();
if (state == arg) {
setState(0);
// 唤醒一个等待的线程
Node h = head;
if (h != null && h.thread != Thread.currentThread()) {
LockSupport.unpark(h.thread);
}
}
}
}
// 使用MyAQS实现独占锁
class MyLock {
private final MyAQS sync = new MyAQS();
public void lock() {
sync.acquire(1);
}
public void unlock() {
sync.release(1);
}
}
// 测试
public class AQSExample {
public static void main(String[] args) {
MyLock lock = new MyLock();
lock.lock();
try {
// 干点啥
} finally {
lock.unlock();
}
}
}
```
代码解释
MyAQS类
继承自`AbstractQueuedSynchronizer`。
重写`tryAcquire(int arg)`方法,尝试获取资源。如果状态为0且能成功原子设置状态为当前线程,则获取锁成功。
重写`release(int arg)`方法,释放资源。如果当前线程持有锁,则将状态设置为0并唤醒一个等待的线程。
MyLock类
包含一个`MyAQS`实例。
`lock()`方法调用`sync.acquire(1)`尝试获取锁。
`unlock()`方法调用`sync.release(1)`释放锁。
AQSExample类
创建`MyLock`实例并测试其功能。
这个示例展示了如何使用AQS实现一个简单的独占锁。AQS的内部机制包括状态管理和等待队列,通过这些机制可以构建更复杂的同步器,如`ReentrantLock`、`Semaphore`等。