Java多线程:使用Semaphore控制方法并发访问数量

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 如何控制某个方法允许并发访问线程的大小?

回答:

在Java中,如果你想控制某个方法的并发访问线程的数量,可以使用Semaphore类。Semaphore是一个计数信号量,它可以用来限制同时访问某个特定资源的线程数量。

以下是一个使用Semaphore来控制并发访问的示例:

import java.util.concurrent.Semaphore;

public class ConcurrencyControl {
    // 创建一个信号量,允许最多3个线程同时访问
    private static final Semaphore semaphore = new Semaphore(3);

    public void limitedAccessMethod() {
        try {
            // 获取一个许可
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " is accessing the method.");
            // 模拟方法执行
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放许可
            semaphore.release();
            System.out.println(Thread.currentThread().getName() + " has finished accessing the method.");
        }
    }

    public static void main(String[] args) {
        ConcurrencyControl control = new ConcurrencyControl();

        // 创建多个线程来测试
        for (int i = 0; i < 10; i++) {
            new Thread(control::limitedAccessMethod, "Thread-" + i).start();
        }
    }
}

代码解析:

  1. Semaphore的创建private static final Semaphore semaphore = new Semaphore(3); 这行代码创建了一个信号量,允许最多3个线程同时访问limitedAccessMethod方法。

  2. 获取许可:在方法开始时,调用semaphore.acquire();来获取一个许可。如果没有可用的许可,线程会被阻塞,直到有许可可用。

  3. 执行方法逻辑:在获取到许可后,线程可以执行方法的逻辑。在这个示例中,我们使用Thread.sleep(2000);来模拟方法的执行时间。

  4. 释放许可:在finally块中,调用semaphore.release();来释放许可,确保即使在发生异常的情况下也能释放。

  5. 创建多个线程:在main方法中,我们创建了10个线程来测试并发访问。

注意事项:

  • 使用Semaphore时要确保在finally块中释放许可,以避免造成死锁。
  • 根据实际需求调整信号量的数量,以控制并发访问的线程数量。