package com.supr; import java.util.concurrent.Semaphore; public class Four { public static void main(String[] args) { final Semaphore s = new Semaphore(3); for (int i = 0; i < 20; i++) { Thread t = new Thread(new Runnable() { @Override public void run() { try { s.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "获取到凭证开始执行.."); System.out.println("当前有"+(3-s.availablePermits())+"个线程并发..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "凭证执行完毕,释放凭证.."); s.release(); } }); t.start(); } } }
Thread-0获取到凭证开始执行.. 当前有1个线程并发... Thread-1获取到凭证开始执行.. 当前有2个线程并发... Thread-2获取到凭证开始执行.. 当前有3个线程并发... Thread-0凭证执行完毕,释放凭证.. Thread-3获取到凭证开始执行.. 当前有3个线程并发... Thread-1凭证执行完毕,释放凭证.. Thread-4获取到凭证开始执行.. 当前有3个线程并发... Thread-2凭证执行完毕,释放凭证.. Thread-5获取到凭证开始执行.. 当前有3个线程并发... Thread-3凭证执行完毕,释放凭证.. Thread-6获取到凭证开始执行.. 当前有3个线程并发... Thread-4凭证执行完毕,释放凭证.. Thread-7获取到凭证开始执行.. 当前有3个线程并发... Thread-5凭证执行完毕,释放凭证.. Thread-8获取到凭证开始执行.. 当前有3个线程并发... Thread-6凭证执行完毕,释放凭证.. Thread-9获取到凭证开始执行.. 当前有3个线程并发... Thread-7凭证执行完毕,释放凭证.. Thread-10获取到凭证开始执行.. Thread-8凭证执行完毕,释放凭证.. 当前有3个线程并发... Thread-11获取到凭证开始执行.. 当前有3个线程并发... Thread-9凭证执行完毕,释放凭证.. Thread-12获取到凭证开始执行.. 当前有3个线程并发... Thread-10凭证执行完毕,释放凭证.. Thread-13获取到凭证开始执行.. 当前有3个线程并发... Thread-11凭证执行完毕,释放凭证.. Thread-14获取到凭证开始执行.. 当前有3个线程并发... Thread-12凭证执行完毕,释放凭证.. Thread-15获取到凭证开始执行.. 当前有3个线程并发... Thread-13凭证执行完毕,释放凭证.. Thread-16获取到凭证开始执行.. 当前有3个线程并发... Thread-14凭证执行完毕,释放凭证.. Thread-17获取到凭证开始执行.. 当前有3个线程并发... Thread-15凭证执行完毕,释放凭证.. Thread-18获取到凭证开始执行.. 当前有3个线程并发... Thread-16凭证执行完毕,释放凭证.. Thread-17凭证执行完毕,释放凭证.. Thread-19获取到凭证开始执行.. 当前有2个线程并发... Thread-18凭证执行完毕,释放凭证.. Thread-19凭证执行完毕,释放凭证..
Semaphore:一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire()
,然后再获取该许可。每个 release()
添加一个许可,从而可能释放一个正在阻塞的获取者。
Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。
说白了,Semaphore是一个计数器,在计数器不为0的时候对线程就放行,一旦达到0,那么所有请求资源的新线程都会被阻塞,包括增加请求到许可的线 程,也就是说Semaphore不是可重入的。每一次请求一个许可都会导致计数器减少1,同样每次释放一个许可都会导致计数器增加1,一旦达到了0,新的 许可请求线程将被挂起。
参考:http://www.blogjava.net/xylz/archive/2010/07/13/326021.html
http://blog.csdn.net/java2000_net/article/details/3997449
http://blog.163.com/maravilla_evol/blog/static/1395646992011912113635724/
http://blog.163.com/liu_sheng_han/blog/static/19059137220128240150242/