在Java的并发编程中,同步器(Synchronizer)是一个非常重要的概念,它用于管理多个线程之间的协作,以确保线程间的正确交互和数据的一致性。Java并发包java.util.concurrent
中提供了多种同步器,这些同步器主要用于实现锁(Locks)和其他并发原语(Concurrency Primitives)。
主要的同步器包括:
Semaphore(信号量):
Semaphore(信号量)是Java中一种非常有用的同步工具,是一种计数器,它用于控制同时访问某个特定资源的线程数量。它可以被用来实现某种形式的资源池,或者限制并发访问某个特定资源的线程数量。Semaphore可以管理一组许可(permits),每个许可代表了一个对共享资源的访问权。
Semaphore的基本工作原理:
初始化:Semaphore在创建时可以指定一个许可的数量,这个数量代表了在任意时刻能够同时访问资源的线程数。
获取许可(acquire):当一个线程想要访问受保护资源时,它必须先获取Semaphore的一个许可。如果Semaphore中还有可用的许可,那么线程就可以继续执行;如果没有可用的许可,线程将会被阻塞,直到有许可被释放为止。
释放许可(release):当线程完成对共享资源的访问后,它应该释放Semaphore中的一个许可,以便其他等待的线程可以获得许可并访问资源。
Semaphore的使用场景非常广泛,比如控制数据库连接的池大小、限制并发访问某个API的线程数量等。
在Java中,Semaphore类位于
java.util.concurrent
包下。示例:
import java.util.concurrent.Semaphore; public class SemaphoreExample { // 创建一个Semaphore,初始许可数量为5 private static final Semaphore semaphore = new Semaphore(5); public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { try { // 请求许可 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " 获取了许可"); // 模拟资源访问,这里只是简单地休眠一段时间 Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " 释放了许可"); // 释放许可 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } }
在这个示例中,我们创建了一个初始许可数量为5的Semaphore。然后,我们启动了10个线程,每个线程都尝试获取许可来访问资源。由于初始许可数量只有5个,因此前5个线程能够立即获取许可并继续执行,而后5个线程将会被阻塞,直到有许可被释放。每个线程在访问完资源后都会释放许可,这样被阻塞的线程就可以获取许可并继续执行了。
CountDownLatch(倒计数锁存器):
CountDownLatch
是Java中一个非常有用的同步器,它属于java.util.concurrent