您好,登录后才能下订单哦!
本篇内容主要讲解“Java中的Semaphore信号量的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中的Semaphore信号量的使用方法”吧!
Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
Semaphore
Semaphore 有两个构造函数,参数为许可的个数 permits 和是否公平竞争 fair。通过 acquire 方法能够获得的许可个数为 permits,如果超过了这个个数,就需要等待。当一个线程 release 释放了一个许可后,fair 决定了正在等待的线程该由谁获取许可,如果是公平竞争则等待时间最长的线程获取,如果是非公平竞争则随机选择一个线程获取许可。不传 fair 的构造函数默认采用非公开竞争。
Semaphore(int permits)
Semaphore(int permits, boolean fair)
一个线程可以一次获取一个许可,也可以一次获取多个。 在 acquire 等待的过程中,如果线程被中断,acquire 会抛出中断异常,如果希望忽略中断继续等待可以调用 acquireUninterruptibly 方法。同时提供了 tryAcquire 方法尝试获取,获取失败返回 false,获取成功返回 true。tryAcquire 方法可以在获取不到时立即返回,也可以等待一段时间。需要注意的是,没有参数的 tryAcquire 方法在有许可可以获取的情况下,无论有没有线程在等待都能立即获取许可,即便是公平竞争也能立即获取。
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 acquireUninterruptibly(int permits)
public boolean tryAcquire(int permits)
public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
public void release(int permits)
使用示例
如下的示例中,测试方法 test 创建了多个线程,每个线程启动后都调用 acquire 方法,然后延时 5s 模仿业务耗时,最后调用 release 方法释放许可。
public class SemaphoreTest {
private int threadNum;
private Semaphore semaphore;
public SemaphoreTest(int permits,int threadNum, boolean fair) {
this.threadNum = threadNum;
semaphore = new Semaphore(permits,fair);
}
private void println(String msg){
SimpleDateFormat sdf = new SimpleDateFormat("[YYYY-MM-dd HH:mm:ss.SSS] ");
System.out.println(sdf.format(new Date()) + msg);
}
public void test(){
for(int i = 0; i < threadNum; i ++){ new Thread(() -> {
try {
semaphore.acquire();
println(Thread.currentThread().getName() + " acquire");
Thread.sleep(5000);//模拟业务耗时
println(Thread.currentThread().getName() + " release");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
公平与非公平
在上述的示例中,如果 fair 传的是 true,则各个线程公平竞争,即按照等待时间的长短决定谁先获取许可。以 9 个线程竞争 3 个许可为例,执行结果如下,首选是线程 0、1、2 获取了许可,5s 后线程 3、4、5 获取了许可,最后是线程 6、7、8 获取许可,顺序基本上与创建线程并启动的先后顺序一致,也与各个线程等待的时间基本相符。
[2017-08-20 21:47:21.817] Thread-0 acquire
[2017-08-20 21:47:21.817] Thread-2 acquire
[2017-08-20 21:47:21.817] Thread-1 acquire
[2017-08-20 21:47:26.830] Thread-1 release
[2017-08-20 21:47:26.830] Thread-0 release
[2017-08-20 21:47:26.830] Thread-4 acquire
[2017-08-20 21:47:26.830] Thread-3 acquire
[2017-08-20 21:47:26.831] Thread-2 release
[2017-08-20 21:47:26.831] Thread-5 acquire
[2017-08-20 21:47:31.831] Thread-4 release
[2017-08-20 21:47:31.831] Thread-3 release
[2017-08-20 21:47:31.831] Thread-6 acquire
[2017-08-20 21:47:31.831] Thread-7 acquire
[2017-08-20 21:47:31.832] Thread-5 release
[2017-08-20 21:47:31.832] Thread-8 acquire
[2017-08-20 21:47:36.831] Thread-6 release
[2017-08-20 21:47:36.831] Thread-7 release
[2017-08-20 21:47:36.832] Thread-8 release
在上述的示例中,如果 fair 传的是 false,则各个线程非公平竞争,随机选取一个线程获取许可。以 9 个线程竞争 3 个许可为例,执行结果如下,首先是线程 0、1、3 获取了许可,5s 后线程 2、5、7 获取了许可,最后是线程 4、6、8 获取许可,与线程创建启动时间无关,也与线程等待时间无关。
[2017-08-20 17:45:09.893] Thread-0 acquire
[2017-08-20 17:45:09.893] Thread-3 acquire
[2017-08-20 17:45:09.893] Thread-1 acquire
[2017-08-20 17:45:14.895] Thread-3 release
[2017-08-20 17:45:14.895] Thread-0 release
[2017-08-20 17:45:14.895] Thread-5 acquire
[2017-08-20 17:45:14.895] Thread-1 release
[2017-08-20 17:45:14.896] Thread-7 acquire
[2017-08-20 17:45:14.896] Thread-2 acquire
[2017-08-20 17:45:19.895] Thread-5 release
[2017-08-20 17:45:19.895] Thread-4 acquire
[2017-08-20 17:45:19.896] Thread-7 release
[2017-08-20 17:45:19.896] Thread-6 acquire
[2017-08-20 17:45:19.896] Thread-2 release
[2017-08-20 17:45:19.896] Thread-8 acquire
[2017-08-20 17:45:24.895] Thread-4 release
[2017-08-20 17:45:24.896] Thread-8 release
[2017-08-20 17:45:24.896] Thread-6 release
到此,相信大家对“Java中的Semaphore信号量的使用方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。