本文主要是介绍使用Semaphore做并发个数控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Semaphore可以控制某个资源可被同时访问的个数,acquire()获取一个许可,如果没有就等待,而release()释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。
另外重入锁ReentrantLock也可以实现该功能,但实现上代码也要复杂些。
SemaPhore,一个信号量对象,可以定义信号量的个数,通过该信号量控制线程同步的数量。例如我们只允许同步三个线程进入共享资源,其它线程都阻塞。
好比,厕所有三个坑,十个人进去,每次只能进去三个。采用信号灯来实现。
其优势为可以被其它线程唤醒,如果使用互斥锁,那么一旦出现异常,该锁将不会释放,该锁只能由自己释放。比如:一个人上厕所,如果采用互斥锁,那么当该人晕倒在厕所时,这个厕所就不能被使用了。如果使用信号灯互斥,那么能够找到物业人员打开厕所,救人并接着使用。
- //构造方法摘要
- Semaphore(int permits)
- //创建具有给定的许可数和非公平的公平设置的 Semaphore。
- Semaphore(int permits, boolean fair)
- //创建具有给定的许可数和给定的公平设置的 Semaphore。
//构造方法摘要
Semaphore(int permits) //创建具有给定的许可数和非公平的公平设置的 Semaphore。
Semaphore(int permits, boolean fair) //创建具有给定的许可数和给定的公平设置的 Semaphore。
下面的Demo,启动7个线程,每次只让三个线程工作,其它线程阻塞。三个线程的工作时间为一个10000以内的随机数。
- package tags;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import
- java.util.concurrent.Semaphore;
- public class TestSemaphore {
- public static void main(String[] args) {
- ExecutorService exec = Executors.newCachedThreadPool();
- // 只能5个线程同时访问
- final Semaphore sp = new Semaphore(3);
- // 模拟10个客户端访问
- for (int index = 0; index < 7; index++) {
- Runnable rb = new Runnable() {
- public void run() {
- try {
- sp.acquire(); // 获取许可
- System.out.println("线程" + Thread.currentThread().getName() +
- "进入,当前已有" + (3-sp.availablePermits()) + "个并发");
- //availablePermits() 返回此信号量中当前可用的许可数。
- Thread.sleep((long) (Math.random() * 10000));
- System.out.println("线程" + Thread.currentThread().getName() + "即将离开");
- sp.release();// 访问完后,释放
- System.out.println("线程" + Thread.currentThread().getName() +
- "已离开,当前有" + (3-sp.availablePermits()) + "个并发");
- } catch (InterruptedException e) {
- }
- }
- };
- exec.execute(rb);
- }
- // 退出线程池
- exec.shutdown();
- }
- }
package tags;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;importjava.util.concurrent.Semaphore;public class TestSemaphore {public static void main(String[] args) {ExecutorService exec = Executors.newCachedThreadPool();// 只能5个线程同时访问final Semaphore sp = new Semaphore(3);// 模拟10个客户端访问for (int index = 0; index < 7; index++) {Runnable rb = new Runnable() {public void run() {try {sp.acquire(); // 获取许可System.out.println("线程" + Thread.currentThread().getName() + "进入,当前已有" + (3-sp.availablePermits()) + "个并发"); //availablePermits() 返回此信号量中当前可用的许可数。Thread.sleep((long) (Math.random() * 10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将离开"); sp.release();// 访问完后,释放System.out.println("线程" + Thread.currentThread().getName() + "已离开,当前有" + (3-sp.availablePermits()) + "个并发"); } catch (InterruptedException e) {}}};exec.execute(rb);}// 退出线程池exec.shutdown();}
}
结果:
线程pool-1-thread-2进入,当前已有2个并发
线程pool-1-thread-3进入,当前已有3个并发
线程pool-1-thread-1进入,当前已有2个并发
线程pool-1-thread-3即将离开
线程pool-1-thread-4进入,当前已有3个并发
线程pool-1-thread-3已离开,当前有3个并发
线程pool-1-thread-2即将离开
线程pool-1-thread-2已离开,当前有2个并发
线程pool-1-thread-7进入,当前已有3个并发
线程pool-1-thread-1即将离开
线程pool-1-thread-5进入,当前已有3个并发
线程pool-1-thread-1已离开,当前有3个并发
线程pool-1-thread-4即将离开
线程pool-1-thread-4已离开,当前有2个并发
线程pool-1-thread-6进入,当前已有3个并发
线程pool-1-thread-7即将离开
线程pool-1-thread-7已离开,当前有2个并发
线程pool-1-thread-6即将离开
线程pool-1-thread-6已离开,当前有1个并发
线程pool-1-thread-5即将离开
线程pool-1-thread-5已离开,当前有0个并发
参考:http://blog.csdn.net/lb85858585/article/details/7273561
JDK:http://www.cjsdn.net/doc/jdk50/java/util/concurrent/Semaphore.html#availablePermits()
转载自:http://uule.iteye.com/blog/1539813
这篇关于使用Semaphore做并发个数控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!