轉載自大佬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