java 信號量
我們知道可以通過信號量控制共享資源的訪問,底層還是AQS這一套,這沒什麼難的。但是有一點可能被大家忽略:聲明信號量的時候,比如只有3個許可證,但是運行過程中,某個時刻的許可證數量是沒有限制的。
比較變態的一點
Semaphore semaphore = new Semaphore(3);
Runnable runnable = () -> {
try {
System.out.println(Thread.currentThread().getName() + "try acquire");
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "acquired semaphore");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
semaphore.release();
// 4個線程都能夠獲取到信號量
for (int i = 0; i < 4; i++) {
new Thread(runnable).start();
}
即使創建信號量的時候,指定了信號量的大小。但是在通過 release()操作釋放信號量任然能超過配置的大小。也就有可能同時執行的線程數量比最開始設置的要大。
沒有任何線程獲取信號量的時候,依然能夠釋放並且釋放的有效。
推薦的做法是一個線程先 acquire 然後 release。如果釋放線程和獲取線程不是同一個,那麼最好保證這種對應關係。不要釋放過多的許可證。