转载自大佬https://www.cnblogs.com/klbc/p/9500947.html
总结了一下:
Semaphore实现为一种基于计数的信号量,Semaphore管理着一组虚拟的许可集合,这种许可可以作为某种凭证,来管理资源,以及线程池的最大并发线程。Semaphore 是 synchronized 的加强版,作用是控制线程的并发数量。
具体方法及解释大佬博客都有。
这里贴上魔改代码(线程池实现)例子:
public class SemaphoreDemo {
public static void main(String args[]) {
final int clientCount = 3;//最多并发数
final int totalRequestCount = 10;//线程总数
Semaphore semaphore = new Semaphore(clientCount);
ExecutorService executorService = Executors.newCachedThreadPool();
SemaphoreService ss=new SemaphoreService();
MyTesk mt=new MyTesk(ss);
for (int i = 0; i < totalRequestCount; i++) {
executorService.execute(mt);
}
executorService.shutdown();
}
}
class SemaphoreService {
private static SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private Semaphore semaphore = new Semaphore(3);// 同步关键类,构造方法传入的数字是多少,则同一个时刻,只运行多少个进程同时运行制定代码
public void doSomething() {
try {
/**
* 在 semaphore.acquire() 和 semaphore.release()之间的代码,同一时刻只允许制定个数的线程进入,
* 因为semaphore的构造方法是3,则同一时刻只允许3个线程进入,其他线程只能等待。
* */
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + ":doSomething start-" + getFormatTimeStr());
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + ":doSomething end-" + getFormatTimeStr());
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println("可用通路数:" + semaphore.availablePermits());
semaphore.release();
}
}
public static String getFormatTimeStr() {
return sf.format(new Date());
}
}
class MyTesk implements Runnable{
private SemaphoreService service;
public MyTesk(SemaphoreService service) {
super();
this.service = service;
}
@Override
public void run() {
this.service.doSomething();
}
pool-1-thread-3:doSomething start-2020-02-22 15:12:03.131
pool-1-thread-2:doSomething start-2020-02-22 15:12:03.131
pool-1-thread-1:doSomething start-2020-02-22 15:12:03.131
pool-1-thread-1:doSomething end-2020-02-22 15:12:05.132
pool-1-thread-2:doSomething end-2020-02-22 15:12:05.132
pool-1-thread-3:doSomething end-2020-02-22 15:12:05.132