在Java中,信号量(Semaphore)是一种用于控制并发访问共享资源的同步机制。它的原理是维护一个计数器,这个计数器表示可以同时访问资源的线程数量。当线程请求访问资源时,信号量的计数器会减少;当线程释放资源时,计数器增加。如果计数器的值小于等于0,任何请求访问的线程都会被阻塞,直到有线程释放资源为止。

Semaphore的基本构造与使用

Java中提供了java.util.concurrent包下的Semaphore类来实现信号量机制。下面是Semaphore的一些基本方法:

  • acquire(): 使线程获取一个许可。如果没有可用的许可,调用线程会被阻塞。
  • release(): 释放一个许可,让其他线程可以获取。
  • tryAcquire(): 尝试获取一个许可,如果成功返回true,否则返回false,且不会阻塞。
  • availablePermits(): 返回当前可用的许可数量。

示例代码

下面的例子展示了如何使用Semaphore来控制多个线程访问共享资源。假设我们有一个有限数量的数据库连接,使用信号量限制同时可以进行数据库操作的线程数。

import java.util.concurrent.Semaphore;

public class DatabaseConnection {
    private static final int MAX_CONNECTIONS = 3; // 最大连接数
    private static final Semaphore semaphore = new Semaphore(MAX_CONNECTIONS, true); // 信号量

    public void accessDatabase(int threadNumber) {
        try {
            // 请求许可
            System.out.println("Thread " + threadNumber + " is trying to access the database.");
            semaphore.acquire(); // 如果没有许可,线程将被阻塞

            System.out.println("Thread " + threadNumber + " has accessed the database.");
            // 模拟数据库操作
            Thread.sleep(2000); // 模拟操作耗时

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("Thread " + threadNumber + " was interrupted.");
        } finally {
            // 释放许可
            System.out.println("Thread " + threadNumber + " is releasing the database.");
            semaphore.release();
        }
    }

    public static void main(String[] args) {
        DatabaseConnection dbConnection = new DatabaseConnection();

        for (int i = 1; i <= 10; i++) {
            int threadNumber = i;
            new Thread(() -> dbConnection.accessDatabase(threadNumber)).start();
        }
    }
}

代码解析

  1. 创建信号量: semaphore被初始化为MAX_CONNECTIONS,这意味着最多允许3个线程同时访问数据库。
  2. 请求访问: 每个线程在访问数据库前调用semaphore.acquire()以请求一个许可。如果当前没有可用的许可,线程将被阻塞。
  3. 数据库操作: 一旦成功获取到许可,线程就可以进行数据库操作。这里我们用Thread.sleep(2000)模拟操作耗时。
  4. 释放许可: 操作完成后,线程必须调用semaphore.release()来释放许可,让其他线程可以继续请求访问。

总结

Java中的信号量是控制并发、限制对共享资源访问的重要机制。通过控制许可数量,可以有效地避免资源争用和线程过度竞争。在实现多线程应用时合理使用信号量,可以提高系统的性能和稳定性。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部