Semaphore可以維護(hù)當(dāng)前訪問自身的線程個(gè)數(shù)贰您,并提供了同步機(jī)制怎抛。使用Semaphore可以控制同時(shí)訪問資源的線程個(gè)數(shù)蚯嫌,例如哲虾,實(shí)現(xiàn)一個(gè)文件允許的并發(fā)訪問數(shù)。
- Semaphore實(shí)現(xiàn)的功能就類似于廁所有5個(gè)坑择示,加入有十個(gè)人要上廁所妒牙,那么同時(shí)能有多少個(gè)人上廁所呢?同時(shí)只能有5個(gè)人能夠占用对妄,當(dāng)5個(gè)人中的任何一個(gè)人讓開后湘今,其中在等待的另外5個(gè)人中又有一個(gè)可以占用了。
- 另外等待的5個(gè)人中可以是隨機(jī)獲得優(yōu)先機(jī)會(huì)剪菱,也可以是按照先來后到的順序獲得機(jī)會(huì)摩瞎,這取決于構(gòu)造Semaphore對(duì)象時(shí)傳入的參數(shù)。
- 單個(gè)信號(hào)量的Semaphore對(duì)象可以實(shí)現(xiàn)互斥鎖的功能孝常,并且可以是由一個(gè)線程獲得了“鎖”旗们,再由另外一個(gè)線程釋放“鎖”,這可應(yīng)用于死鎖恢復(fù)的一些場合构灸。
實(shí)例:
管理停車位上渴,一個(gè)小的電子設(shè)備,實(shí)時(shí)性強(qiáng)就要Semaphore。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class TestSemaphore {
private static final int NUM = 3;
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final Semaphore sp = new Semaphore(3);
for (int i = 0; i < 10; i++) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
sp.acquire();//獲取坑位
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程 " + Thread.currentThread().getName()
+ "進(jìn)入稠氮,當(dāng)前已有" + (NUM-sp.availablePermits() + "個(gè)并發(fā)"));
try {
Thread.sleep((long)Math.random() * 10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程 " + Thread.currentThread().getName() + "即將離開");
sp.release();//釋放當(dāng)前線程占用的坑位
System.out.println("線程 " + Thread.currentThread().getName()
+ "已離開曹阔,當(dāng)前已有" + (NUM-sp.availablePermits() + "個(gè)并發(fā)"));
}
}; //Runnable Def
service.execute(run);
} //for
service.shutdown();
while (!service.isTerminated()) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("結(jié)束了!");
}
}