Java 并发工具类之 Semaphore
  anLrwkgbyYZS 2023年12月30日 18 0


Semaphore 控制访问特定资源的线程数量,新建规定数量的许可证,获得许可证可以继续执行,未获得需要阻塞,执行完成归还许可证,这样其余的线程(未获得许可证)才可以执行。例如:Semaphore用于流量控制,例如只有10个数据库连接,可以用Semaphore控制只有10个线程访问数据库,这样就不会报错无法获取数据库连接。

 1. Semaphore的部分方法

方法

描述

public Semaphore(int permits)

构造函数:设置许可证数permits。

public Semaphore(int permits, boolean fair)

设置许可证数permits, fair 为 true 使用先进先出的公平策略,false则不公平。

public void acquire()

获取许可证。

public void acquireUninterruptibly() 

不可中断的获取许可证。

public boolean tryAcquire()

尝试获取许可证,没有许可证不阻塞

public boolean tryAcquire(long timeout, TimeUnit unit)

等待一定时间,一直没有获得许可证不再阻塞

public void release()

归还许可证

public void acquire(int permits)

获取给定数量的许可证

public void release(int permits)

归还给定数量的许可证

public final boolean hasQueuedThreads()

是否有线程在等待

public final int getQueueLength()

等待线程的数量

protected Collection<Thread> getQueuedThreads()

返回所有等待许可的线程集合

public int availablePermits()

剩余许可证

2. 测试代码

许可证数量初始为 3 。

private static Semaphore semaphore = new Semaphore(3);

测试代码如下所示,开启10个线程获取数据库连接,因为只有三个许可证,三个许可证被获取后,其他线程需要等待当前的三个线程释放许可证才可以获取许可证,所以三个数据库连接、三个数据库连接被获取: 

public class SemaphoreStudy implements Runnable{
    private static Semaphore semaphore = new Semaphore(3);

    @Override
    public void run() {
        try {
            semaphore.acquire();
            System.out.print("获得数据库连接");
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        semaphore.release();
    }

    public static void main(String[] args) {
        for (int i=0; i<10; i++) {;
            new Thread(new SemaphoreStudy()).start();
        }
    }
}

运行截图,三个、三个数据库连接被获取。

Java 并发工具类之 Semaphore_数据库连接

使用 tryAcquire() 进行修改, tryAcquire() 尝试获取许可证,没有许可证不阻塞,测试代码如下:

public class SemaphoreStudy implements Runnable{
    private static Semaphore semaphore = new Semaphore(3);

    @Override
    public void run() {
        try {
            if (semaphore.tryAcquire()) {
                System.out.println("获得数据库连接");
                TimeUnit.MILLISECONDS.sleep(1000);
                semaphore.release();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        for (int i=0; i<10; i++) {;
            new Thread(new SemaphoreStudy()).start();
        }
    }
}

运行截图,7个获取不到许可证的线程,不阻塞等待:

Java 并发工具类之 Semaphore_ide_02

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月30日 0

暂无评论

推荐阅读
  anLrwkgbyYZS   2023年12月30日   12   0   0 i++iosi++ioscici
  anLrwkgbyYZS   2023年12月30日   14   0   0 ideciciMaxideMax
anLrwkgbyYZS