多執行緒 之Semaphore 訊號量控制
阿新 • • 發佈:2018-11-19
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,但是每次只能允許兩個執行緒獲得訊號得以消費,其餘得等待獲得訊號量