1. 程式人生 > >多執行緒 之Semaphore 訊號量控制

多執行緒 之Semaphore 訊號量控制

Semaphore(訊號量) 用來控制同時訪問特定資源的執行緒數量。可以起到限流的作用。它與之前寫到的Guava API 中的令牌桶 RateLimiter的區別在於,令牌桶是控制了最終能進入訪問資源的恆定流量。會拋棄掉一些過剩流量的進入。而Semaphore 保證的是進入流量的恆定速率,這些流量最終都可以進入訪問資源,只是已一定的速率。

public class SemaphoreTest2 {

	final Semaphore_copy sc = new Semaphore_copy(2,true);
	
	private static class Semaphore_copy extends Semaphore{
		
		public Semaphore_copy(int permits,boolean fair){
			super(permits, fair);
		}
		
		@Override
		protected Collection<Thread> getQueuedThreads() {
			List<Thread> list = new ArrayList<>(super.getQueuedThreads());
			Collections.reverse(list);
			return list;
		}
		
	}
	
	public void dosomethings(){
		try {
			sc.acquire();
			System.out.println(Thread.currentThread().getName()+" get the Semaphore>>> "+sc.getQueuedThreads().stream().map(t -> t.getName()).collect(Collectors.toList())+" are waiting...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			sc.release();
		}
	}
	public static void main(String[] args) {
		SemaphoreTest2 st = new SemaphoreTest2();
		ThreadPoolExecutor pool  = new ThreadPoolExecutor(4, 8, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20));
		for(int i = 0;i<20;i++){
			pool.execute(new Thread(()->st.dosomethings()));
		}
		pool.shutdown();
		
	}
}

以上程式碼執行結果 


訊號量控制為2,執行緒池中核心執行緒數為4,但是每次只能允許兩個執行緒獲得訊號得以消費,其餘得等待獲得訊號量