Semaphore中管理着一组虚拟的许可,许可的初始数量可通过构造函数来指定
public Semaphore(int permits, boolean fair)
public Semaphore(int permits)
,执行操作时可以首先获得许可
semaphore.acquire();
,并在使用后释放许可
semaphore.release();
如果没有许可,那么acquire方法将会一直阻塞直到有许可(或者直到被终端或者操作超时)。
作用:可以用来控制同时访问某个特定资源的操作数量,或者某个操作的数量。
public class SemaphoreDemo {
// 对资源列表进行同步
private final ReentrantLock lock = new ReentrantLock();
// 信号量
private final Semaphore semaphore;
// 可使用的资源列表
private final LinkedList<Object> resourceList = new LinkedList<Object>();
public SemaphoreDemo(Collection<Object> resourceList) {
this.resourceList.addAll(resourceList);
semaphore = new Semaphore(resourceList.size(), true);
}
public static void main(String[] args) throws InterruptedException {
LinkedList<Object> resources = new LinkedList<Object>();
resources.add("resource1");
resources.add("resource2");
// 准备工作任务
final SemaphoreDemo demo = new SemaphoreDemo(resources);
Runnable worker = new Runnable() {
@Override
public void run() {
Object resource = null;
try {
// 获取资源
resource = demo.acquire();
System.out.println(Thread.currentThread().getName()
+ "--twork ont" + resource);
// 用resource做工作
Thread.sleep(new Random().nextInt(10000)/10);
System.out.println(Thread.currentThread().getName()
+ "--tfinish ont" + resource);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 归还资源
if (resource != null) {
demo.release(resource);
}
}
}
};
// 启动9个任务
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 9; i++) {
service.submit(worker);
}
service.shutdown();
System.out.println("shutdown");
boolean isTerminate = service.awaitTermination(1000, TimeUnit.MILLISECONDS);
System.out.println("awaite : " + isTerminate);
}
public Object acquire() throws InterruptedException {
semaphore.acquire();
lock.lock();
try {
return resourceList.poll();
} finally {
lock.unlock();
}
}
public void release(Object resource) {
lock.lock();
try {
resourceList.add(resource);
} finally {
lock.unlock();
}
semaphore.release();
}
}
结果:
pool-1-thread-1--twork ontresource1
pool-1-thread-2--twork ontresource2
shutdown
pool-1-thread-2--tfinish ontresource2
pool-1-thread-3--twork ontresource2
pool-1-thread-1--tfinish ontresource1
pool-1-thread-4--twork ontresource1
pool-1-thread-3--tfinish ontresource2
pool-1-thread-5--twork ontresource2
pool-1-thread-4--tfinish ontresource1
pool-1-thread-6--twork ontresource1
awaite : false
pool-1-thread-6--tfinish ontresource1
pool-1-thread-7--twork ontresource1
pool-1-thread-5--tfinish ontresource2
pool-1-thread-8--twork ontresource2
pool-1-thread-8--tfinish ontresource2
pool-1-thread-9--twork ontresource2
pool-1-thread-7--tfinish ontresource1
pool-1-thread-9--tfinish ontresource2
如果
boolean isTerminate = service.awaitTermination(1000, TimeUnit.MILLISECONDS);
的1000改为1000*100,此时间大于运行总时间
结果:
pool-1-thread-1--twork ontresource1
pool-1-thread-2--twork ontresource2
shutdown
pool-1-thread-1--tfinish ontresource1
pool-1-thread-3--twork ontresource1
pool-1-thread-2--tfinish ontresource2
pool-1-thread-4--twork ontresource2
pool-1-thread-4--tfinish ontresource2
pool-1-thread-5--twork ontresource2
pool-1-thread-3--tfinish ontresource1
pool-1-thread-6--twork ontresource1
pool-1-thread-5--tfinish ontresource2
pool-1-thread-7--twork ontresource2
pool-1-thread-7--tfinish ontresource2
pool-1-thread-8--twork ontresource2
pool-1-thread-8--tfinish ontresource2
pool-1-thread-9--twork ontresource2
pool-1-thread-6--tfinish ontresource1
pool-1-thread-9--tfinish ontresource2
awaite : true