Java多线程之并发编程的核心AQS详解
什么是AQS
AQS,即AbstractQueuedSynchronizer,是Java多线程并发包(java.util.concurrent)中的一个核心组件,用于构建锁和其他同步工具的基础框架。
AQS 中提供了一些基本的同步状态管理功能,包括获取和释放锁、管理同步状态、阻塞线程等。AQS 的一个重要特性是可以通过继承它来构建具有同步功能的自定义组件。
AQS的使用
在使用 AQS 构建自定义同步组件时,通常需要实现以下两个方法:
- tryAcquireShared(int arg):请求共享资源,如果当前 AQS 对象的同步状态可以被获取,则返回 true,否则返回 false。
- tryReleaseShared(int arg):释放共享资源。
这两个方法将被 AQS 的模板方法调用,处理线程的阻塞和唤醒等操作。
AQS 用于构建的同步工具包括锁和信号量等。下面分别以 ReentrantLock 和 CountDownLatch 为例,了解 AQS 的具体使用。
ReentrantLock
ReentrantLock 是 Java 中的一个可重入锁实现,可以通过内部维护的同步状态来保证同一时间只有一个线程能够获取到锁。
下面是一个使用 ReentrantLock 实现的示例代码:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyRunnable implements Runnable {
private Lock lock = new ReentrantLock();
private int count = 0;
public void run() {
lock.lock(); //获取锁
try {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " count: " + count++);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //释放锁
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
Thread thread2 = new Thread(myRunnable);
thread1.start();
thread2.start();
}
}
通过调用 ReentrantLock 的 lock() 方法获取锁,然后在 finally 块中调用 unlock() 方法释放锁。这里的 lock() 方法和 synchronized 块的作用一致,防止多个线程同时对 count 变量进行操作。
CountDownLatch
CountDownLatch 是 Java 中的一个同步工具类,它可以阻塞线程,直到指定数量的事件已经发生。
以下是一个使用 CountDownLatch 实现的示例代码:
import java.util.concurrent.CountDownLatch;
public class Main {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " is running");
countDownLatch.countDown(); //事件发生后,调用 countDownLatch.countDown() 通知
}).start();
}
countDownLatch.await(); //阻塞主线程,直到5个事件都已经发生
System.out.println("All threads are finished");
}
}
使用 CountDownLatch 的 await() 方法可以阻塞主线程,直到 countDownLatch 对象的计数器为 0。每个工作线程完成工作后,调用 countDownLatch.countDown() 通知计数器减 1,表示一个事件已经发生。
总结
通过 AQS,我们可以方便地实现多种同步工具,包括锁、信号量等。在使用 AQS 构建自定义同步组件时,我们需要实现 tryAcquireShared 和 tryReleaseShared 两个方法,并在模板方法中进行调用。 AQS 可以说是 Java 并发编程中不可忽视的重要组件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之并发编程的核心AQS详解 - Python技术站