介绍

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 是一个计数信号量,可以用于限制许可数量,但它本身并不能保证线程安全。在多线程环

境中,如果需要保证线程安全,还需要使用其他的同步机制,如锁或原子操作。