Semaphore 維護一組許可證,控制同時訪問資源的線程數。核心方法:
acquire():獲取一個許可,無則阻塞acquire(int permits):獲取多個許可release():釋放一個許可release(int permits):釋放多個許可availablePermits():當前可用許可數本質是「共享鎖」的泛化:Semaphore(1) 相當於互斥鎖。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class Test {
public static void main(String[] args) {
MyPool myPool = new MyPool(20); // 池大小20
ExecutorService threadPool = Executors.newFixedThreadPool(2);
threadPool.execute(new MyThread("任務A", myPool, 3));
threadPool.execute(new MyThread("任務B", myPool, 12));
threadPool.execute(new MyThread("任務C", myPool, 7));
threadPool.shutdown();
}
}
class MyPool {
private Semaphore sp;
MyPool(int size) { this.sp = new Semaphore(size); }
public Semaphore getSp() { return sp; }
}
class MyThread extends Thread {
private String threadname; private MyPool pool; private int x;
MyThread(String threadname, MyPool pool, int x) {
this.threadname = threadname; this.pool = pool; this.x = x;
}
public void run() {
try {
pool.getSp().acquire(x); // 申請許可
System.out.println(threadname + "成功獲取了" + x + "個許可!");
} catch (InterruptedException e) { e.printStackTrace(); }
finally {
pool.getSp().release(x); // 歸還許可
System.out.println(threadname + "釋放了" + x + "個許可!");
}
}
}
任務B成功獲取了12個許可!
任務B釋放了12個許可!
任務A成功獲取了3個許可!
任務C成功獲取了7個許可!
任務C釋放了7個許可!
任務A釋放了3個許可!
Process finished with exit code 0
分析:池許可 20。任務B 先獲取12(剩8),任務A獲取3(剩5),任務C獲取7(不足阻塞),B釋放12後C獲取成功。
new Semaphore(permits, true) 公平模式作者指出:Semaphore 無法直接獲取等待線程、持有許可線程信息,監控能力弱。生產環境常結合 ThreadPoolExecutor 監控指標或自定義封裝增強可觀測性。