介绍
Semaphore
是 Java 中的一个并发类,用于控制并发访问资源的线程数量。它可以用来限制同时访问某个资源的线程数量,或者在有限资源池中进行资源分配。
Semaphore
维护了一个许可计数,表示可用的许可数量。线程可以通过调用 acquire
方法获取许可,如果许可数量为正,则线程可以立即获取许可;否则,线程将被阻塞,直到有其他线程释放许可。每个成功获取许可的线程都需要调用 release
方法来释放许可,以便其他线程可以获取许可。
Semaphore
类提供了以下常用方法:
-
acquire()
:获取一个许可,如果没有可用的许可,则线程将被阻塞,直到有其他线程释放许可。 -
acquire(int permits)
:获取指定数量的许可,如果可用许可数量不足,则线程将被阻塞,直到有其他线程释放足够数量的许可。 -
release()
:释放一个许可,将许可数量加一。 -
release(int permits)
:释放指定数量的许可,将许可数量加上指定数量。 -
availablePermits()
:返回当前可用的许可数量。
示例
下面是一个使用 Semaphore
的示例,展示了如何限制同时访问资源的线程数量:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private static final int THREAD_COUNT = 5;
private static final int MAX_CONCURRENT_TASKS = 2;
private static Semaphore semaphore = new Semaphore(MAX_CONCURRENT_TASKS);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
Thread thread = new Thread(new Task());
thread.start();
}
}
static class Task implements Runnable {
@Override
public void run() {
try {
System.out.println("Thread " + Thread.currentThread().getName() + " is waiting for a permit.");
semaphore.acquire();
System.out.println("Thread " + Thread.currentThread().getName() + " gets a permit.");
// 模拟任务执行
Thread.sleep(2000);
System.out.println("Thread " + Thread.currentThread().getName() + " releases the permit.");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在上述示例中,我们创建了一个包含 5 个线程的线程池。通过 Semaphore
,我们限制了同时执行的任务数量为 2。每个线程在执行任务之前通过 acquire
方法获取许可,然后执行任务,最后通过 release
方法释放许可。在任意时刻,最多只有两个线程可以同时执行任务,其他线程需要等待许可的释放。
注意,Semaphore
是一个计数信号量,可以用于限制许可数量,但它本身并不能保证线程安全。在多线程环
境中,如果需要保证线程安全,还需要使用其他的同步机制,如锁或原子操作。