操作系統(tǒng)的信號量是個很重要的概念,在進(jìn)程控制方面都有應(yīng)用。Java并發(fā)庫的 Semaphore可以很輕松完成信號量控制,Semaphore可以控制某個資源可被同時訪問的個數(shù),acquire()獲取一個許可,如果沒有就等待,而release()釋放一個許可。比如在Windows下可以設(shè)置共享文件的最大客戶端訪問個數(shù)。
Semaphore維護(hù)了當(dāng)前訪問的個數(shù),提供同步機制,控制同時訪問的個數(shù)。在數(shù)據(jù)結(jié)構(gòu)中鏈表可以保存“無限”的節(jié)點,用Semaphore可以實現(xiàn)有限大小的鏈表。另外重入鎖ReentrantLock也可以實現(xiàn)該功能,但實現(xiàn)上要負(fù)責(zé)些,代碼也要復(fù)雜些。
下面的Demo中申明了一個只有5個許可的Semaphore,而有20個線程要訪問這個資源,通過acquire()和release()獲取和釋放訪問許可。
package concurrent;
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore;
public class TestSemaphore { public static void main(String[] args) { // 線程池 ExecutorService exec = Executors.newCachedThreadPool(); // 只能5個線程同時訪問 final Semaphore semp = new Semaphore(5); // 模擬20個客戶端訪問 for (int index = 0; index < 20; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { // 獲取許可 semp.acquire(); System.out.println("Accessing: " + NO); Thread.sleep((long) (Math.random() * 10000)); // 訪問完后,釋放 semp.release(); } catch (InterruptedException e) { } } }; exec.execute(run); } // 退出線程池 exec.shutdown(); } } |
運行結(jié)果: Accessing: 0 Accessing: 1 Accessing: 2 Accessing: 3 Accessing: 4 Accessing: 5 Accessing: 6 Accessing: 7 Accessing: 8 Accessing: 9 Accessing: 10 Accessing: 11 Accessing: 12 Accessing: 13 Accessing: 14 Accessing: 15 Accessing: 16 Accessing: 17 Accessing: 18 Accessing: 19
|