您好,登錄后才能下訂單哦!
這篇文章主要介紹java并發之同步輔助類semaphore的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
信號量就是可以聲明多把鎖(包括一把鎖:此時為互斥信號量)。
舉個例子:一個房間如果只能容納5個人,多出來的人必須在門外面等著。如何去做呢?一個解決辦法就是:房間外面掛著五把鑰匙,每進去一個人就取走一把鑰匙,沒有鑰匙的不能進入該房間而是在外面等待。每出來一個人就把鑰匙放回原處以方便別人再次進入。
常用方法
acquire():獲取信號量,信號量內部計數器減1
release():釋放信號量,信號量內部計數器加1
tryAcquire():這個方法試圖獲取信號量,如果能夠獲取返回true,否則返回false
信號量控制的線程數量在聲明時確定。例如:
Semphore s = new Semphore(2);
一個例子
實現一個功能:一個打印隊列,被三臺打印機打印
package semaphore;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintQueue {
//信號量
private Semaphore semaphore;
//是否空閑打印機
private boolean freePrinters[];
private Lock lockPrinters;
public PrintQueue(){
//初始化三個信號
semaphore=new Semaphore(3);
//三臺空閑打印機
freePrinters=new boolean[3];
for (int i=0; i<3; i++){
freePrinters[i]=true;
}
lockPrinters=new ReentrantLock();
}
public void printJob (Object document){
try {
//獲取信號量
semaphore.acquire();
int assignedPrinter=getPrinter();
Long duration=(long)(Math.random()*10);
System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
TimeUnit.SECONDS.sleep(duration);
freePrinters[assignedPrinter]=true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// Free the semaphore
semaphore.release();
}
}
private int getPrinter() {
int ret=-1;
try {
lockPrinters.lock();
for (int i=0; i<freePrinters.length; i++) {
if (freePrinters[i]){
ret=i;
freePrinters[i]=false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lockPrinters.unlock();
}
return ret;
}
}
聲明一個Job類,使用打印隊列:
package semaphore;
public class Job implements Runnable {
private PrintQueue printQueue;
public Job(PrintQueue printQueue){
this.printQueue=printQueue;
}
@Override
public void run() {
System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
}
}
測試:
package semaphore;
public class MainCmd {
public static void main (String args[]){
PrintQueue printQueue=new PrintQueue();
//啟動12個打印線程
Thread thread[]=new Thread[12];
for (int i=0; i<12; i++){
thread[i]=new Thread(new Job(printQueue),"Thread "+i);
}
for (int i=0; i<12; i++){
thread[i].start();
}
}
}
需要注意的地方
1、對于信號量聲明的臨界區,雖然可以控制線程訪問的數量,但是不能保證代碼塊之間是線程安全的。所以上面的例子在方法printJob()方法里面使用了鎖保證數據安全性。
2、信號量也涉及到公平性問題。和鎖公平性一樣,這里默認是非公平的。可以通過構造器顯示聲明鎖的公平性。
public Semaphore(int permits, boolean fair)
應用場景
流量控制,即控制能夠訪問的最大線程數。
以上是“java并發之同步輔助類semaphore的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。