源码注释里面有例子;
主要方法是 :
acquire() 子线程调用,申请一个令牌,不一定会获取到,该方法是阻塞方法,获取不到的子线程等待,等有可用令牌时去
release() 子线程调用,令牌会释放(前提你得获取到令牌否则你释放啥。。。)
/**
* 厕所4个位子,6个人--资源不够
* 一般结合线程池使用
*/
public class SemaphoreTest {
static int permits = 4;
//是否公平锁
static boolean booFair;
private static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 10, 60,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(permits, booFair);
String[] name = {"李明", "王五", "张杰", "王强", "赵二", "李四", "张三"};
for (int i = 0; i < 7; i++) {
Thread t1 = new WCThread(name[i], semaphore);
threadPool.execute(t1);
// threadPool.submit(t1);
}
try {
//主线程等待线程池里面的线程去执行
//一定要大于线程 时间的2倍(N/permits)
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 4
System.out.println("过了一会,当前可使用的许可数为:" + semaphore.availablePermits());
threadPool.shutdown();
}
private static class WCThread extends Thread {
private String name;
Semaphore semaphore;
public WCThread(String s, Semaphore semaphore) {
this.name = s;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
System.out.println(name + "--占到坑位一个^_^");
semaphore.acquire();
//模拟耗时操作 业务1--此处就是大号。。。
TimeUnit.SECONDS.sleep(5);
System.out.println("当前可使用的许可数为:" + semaphore.availablePermits()+"at"+System.currentTimeMillis());
semaphore.release();
System.out.println(name + "--出WC 坑位+1^_^");
System.out.println("当前可使用的许可数为:" + semaphore.availablePermits()+"at"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
//后续可以做 业务2--洗手等
}
}
}