AQS(AbstractQueuedSynchronizer)是Java中用于实现同步器的框架,位于java.util.concurrent.locks
包下。它提供了一种灵活且强大的方式来实现各种同步机制,例如锁、计数器、信号量等。AQS的设计基于FIFO(先进先出)等待队列,通过内部的状态来管理线程的获取和释放锁的操作。
acquire(int arg)
:
用于独占模式,当线程尝试获取锁时调用。arg
参数是一个用于表示状态的值。
release(int arg)
:
用于独占模式,当线程释放锁时调用。arg
参数是一个用于表示状态的值。
acquireShared(int arg)
:
用于共享模式,当线程尝试获取共享资源时调用。arg
参数也是一个用于表示状态的值。
releaseShared(int arg)
:
用于共享模式,当线程释放共享资源时调用。arg
参数是一个用于表示状态的值。
tryAcquire(int arg)
:
尝试以独占模式获取同步状态,成功返回true,失败返回false。
tryRelease(int arg)
:
尝试以独占模式释放同步状态,成功返回true,失败返回false。
tryAcquireShared(int arg)
:
尝试以共享模式获取同步状态,成功返回true,失败返回false。
tryReleaseShared(int arg)
:
尝试以共享模式释放同步状态,成功返回true,失败返回false。
isHeldExclusively()
:
查询当前同步器是否在独占模式下被当前线程所持有。
在 AQS中,同步状态(state)的含义由具体的同步器决定。通常情况下,0 表示未被锁定状态,1 或者其他非零值表示已经被锁定状态。
在独占锁的情况下,常见的含义是:
-
0(未锁定):表示资源没有被线程占用,可以被当前线程或其他线程获取。
-
1(已锁定):表示资源已经被某个线程独占,其他线程无法获取,必须等待释放。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class AQSStateExample {
private static Lock lock = new ReentrantLock();
public static void main(String[] args) {
// 同步状态为0表示未锁定
System.out.println("Lock state before acquisition: " + ((ReentrantLock) lock).getHoldCount());
// 尝试获取锁,同步状态变为1
lock.lock();
try {
System.out.println("Lock state after acquisition: " + ((ReentrantLock) lock).getHoldCount());
} finally {
// 释放锁,同步状态变为0
lock.unlock();
System.out.println("Lock state after release: " + ((ReentrantLock) lock).getHoldCount());
}
}
}
在这个例子中,getHoldCount
方法用于获取当前线程保持锁的次数。在未获取锁时,同步状态为0。在获取锁后,同步状态变为1。在释放锁后,同步状态重新变为0。
以下是创建一个简单的独占锁,允许一个线程独占资源,其他线程必须等待。
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
class MyExclusiveLock {
private final Sync sync = new Sync();
public void lock() {
sync.acquire(1);
}
public void unlock() {
sync.release(1);
}
private static class Sync extends AbstractQueuedSynchronizer {
// 实现 AQS 的抽象方法
@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 IllegalMonitorStateException();
}
// 释放锁
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override
protected boolean isHeldExclusively() {
// 判断当前线程是否持有锁
return getExclusiveOwnerThread() == Thread.currentThread();
}
}
}
public class AQSExample {
public static void main(String[] args) {
MyExclusiveLock myLock = new MyExclusiveLock();
// 线程1获取锁
new Thread(() -> {
myLock.lock();
try {
System.out.println("Thread 1 acquired the lock.");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
myLock.unlock();
System.out.println("Thread 1 released the lock.");
}
}).start();
// 线程2尝试获取锁(会被阻塞)
new Thread(() -> {
myLock.lock();
try {
System.out.println("Thread 2 acquired the lock.");
} finally {
myLock.unlock();
System.out.println("Thread 2 released the lock.");
}
}).start();
}
}