Java 并发编程中的 java.util.concurrent
(简称 JUC)包提供了多种高级并发工具,其中包括 Condition
接口和 AbstractQueuedSynchronizer
(简称 AQS)框架。下面将详细介绍这些概念。
Condition 接口
Condition
接口是 java.util.concurrent.locks
包中的一个接口,它提供了比 wait()
和 notify()
更高级的线程等待/通知机制。Condition
接口通常与 Lock
接口一起使用,以实现更细粒度的线程同步。
Condition 的主要方法
- await():使当前线程等待,直到被另一个线程唤醒或被中断。
- signal():唤醒一个等待的线程。
- signalAll():唤醒所有等待的线程。
示例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean ready = false;
public void await() throws InterruptedException {
lock.lock();
try {
while (!ready) {
condition.await();
}
System.out.println("Thread resumed after being signaled.");
} finally {
lock.unlock();
}
}
public void signal() {
lock.lock();
try {
ready = true;
condition.signal();
} finally {
lock.unlock();
}
}
}
在这个示例中,我们创建了一个 ReentrantLock
实例,并从中获取了一个 Condition
实例。await
方法使线程等待,直到 signal
方法被调用。signal
方法唤醒等待的线程。
AbstractQueuedSynchronizer (AQS)
AbstractQueuedSynchronizer
(简称 AQS)是 java.util.concurrent
包中的一个抽象类,它为实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器提供了框架。AQS 是许多 Java 并发工具的基础,例如 ReentrantLock
, Semaphore
, CountDownLatch
等。
AQS 的主要组件
- 独占模式(Exclusive Mode):一个线程可以独占资源。例如,写操作通常以独占模式进行,因为一次只能有一个写线程执行。
- 共享模式(Shared Mode):多个线程可以共享资源。例如,读操作通常以共享模式进行,因为多个读线程可以同时执行。
AQS 的主要方法
- acquire(int arg):获取资源。如果资源不可用,则将当前线程加入等待队列,并阻塞当前线程。
- release(int arg):释放资源。如果释放后有线程在等待,则释放一个线程。
- tryAcquire(int arg):尝试获取资源。如果资源可用,则立即返回成功;否则返回失败。
- tryRelease(int arg):尝试释放资源。如果资源释放成功,则返回成功;否则返回失败。
- acquireShared(int arg):以共享模式获取资源。
- releaseShared(int arg):以共享模式释放资源。
示例
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
public class SimpleSemaphore extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 7316153563782823691L;
protected int permitCount = 1;
@Override
protected boolean tryAcquire(int acquires) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int releases) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void acquire() throws InterruptedException {
acquire(1);
}
public boolean release() {
return release(1);
}
public static void main(String[] args) throws InterruptedException {
SimpleSemaphore semaphore = new SimpleSemaphore();
semaphore.acquire();
semaphore.release();
}
}
在这个示例中,我们创建了一个名为 SimpleSemaphore
的类,它继承自 AbstractQueuedSynchronizer
。我们重写了 tryAcquire
和 tryRelease
方法来实现独占模式的获取和释放资源。
总结
Condition
接口提供了比传统 wait()
和 notify()
更高级的线程等待/通知机制,可以实现更细粒度的线程同步。而 AbstractQueuedSynchronizer
(AQS)则是实现锁和其他同步工具的基础框架,它为实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器提供了抽象模板。
在实际开发中,Condition
和 AQS 是非常有用的工具,可以帮助开发者实现更复杂、更高效的并发控制逻辑。使用这些工具可以避免常见的并发问题,如死锁和竞态条件,同时还可以提高程序的性能。