java.util.concurrent.Semaphore
信號量是一種計數器,用來保護一個或者多個共享資源的訪問,它是併發編程的一種基礎工具。
信號量通過計數器的方式來對資源進行訪問控制
當其計數器值大於0時,表示有資源可以訪問
當其計數器值等於0時,線程將進入休眠狀態直到計數器值大於0
通過信號量的構造函數指定資源數量:
private final Semaphore semaphore = new Semaphore(1);
表示該信號量的計數器值只能爲0或者1,也稱爲二進制信號量
這樣可以限制每次執行的線程只有一個
信號量的使用:
private final Semaphore semaphore = new Semaphore(1);
public void a() {
try {
//獲取信號量的鎖
semaphore.acquire();
//對共享資源進行操作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//釋放信號量
semaphore.release();
}
}
信號量也有對應的tryAcquire()方法,和Lock的tryLock()一樣
使用信號量控制資源的多副本併發訪問控制
<pre style="background-color: rgb(255, 255, 255); font-family: Consolas; font-size: 10.5pt;"><pre name="code" class="java">public class TestSemaphore {
//信號量控制資源的狀態
private final Semaphore semaphore;
//資源數組,true表示可用(空閒)
private boolean[] resources;
//保護對資源數組的訪問
private Lock lock;
//資源數量
private int resourceCount = 3;
public TestSemaphore() {
semaphore = new Semaphore(resourceCount);
resources = new boolean[resourceCount];
for (int i = 0; i < resourceCount; i++) {
resources[i] = true;
}
lock = new ReentrantLock();
}
public void doSth() {
try {
semaphore.acquire();
int resource = getResource();
//使用resource進行操作
//任務完成,把對應的resource置爲空閒
resources[resource] = true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//釋放信號量
semaphore.release();
}
}
/**
* 獲取空閒的資源
*
* @return 空閒的資源下標,沒有就返回-1
*/
private int getResource() {
//資源下標
int ret = -1;
try {
lock.lock();
for (int i = 0; i < resources.length; i++) {
if (resources[i]) {
ret = i;
resources[i] = false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return ret;
}
}