使用方法:
1.SynchronousQueue
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor(4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), r -> new Thread(r, "ThreadTest"));
SynchronousQueue沒有容量,是無緩沖等待隊列,是一個不存儲元素的阻塞隊列,會直接將任務交給消費者,必須等隊列中的添加元素被消費后才能繼續添加新的元素。
擁有公平(FIFO)和非公平(LIFO)策略,非公平側羅會導致一些數據永遠無法被消費的情況?
使用SynchronousQueue阻塞隊列一般要求maximumPoolSizes為無界(Integer.MAX_VALUE),避免線程拒絕執行操作。
2.LinkedBlockingQueue
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor(4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), r -> new Thread(r, "ThreadTest"));
LinkedBlockingQueue是一個無界緩存等待隊列。當前執行的線程數量達到corePoolSize的數量時,剩余的元素會在阻塞隊列里等待。(所以在使用此阻塞隊列時maximumPoolSizes就相當於無效了),每個線程完全獨立於其他線程。生產者和消費者使用獨立的鎖來控制數據的同步,即在高並發的情況下可以並行操作隊列中的數據。
注:這個隊列需要注意的是,雖然通常稱其為一個無界隊列,但是可以人為指定隊列大小,而且由於其用於記錄隊列大小的參數是int類型字段,所以通常意義上的無界其實就是隊列長度為 Integer.MAX_VALUE,且在不指定隊列大小的情況下也會默認隊列大小為 Integer.MAX_VALUE,等同於如下:
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor(4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(Integer.MAX_VALUE), r -> new Thread(r, "ThreadTest"));
3.ArrayBlockingQueue
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor(4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(32), r -> new Thread(r, "ThreadTest"));
ArrayBlockingQueue是一個有界緩存等待隊列,可以指定緩存隊列的大小,當正在執行的線程數等於corePoolSize時,多余的元素緩存在ArrayBlockingQueue隊列中等待有空閑的線程時繼續執行,當ArrayBlockingQueue已滿時,加入ArrayBlockingQueue失敗,會開啟新的線程去執行,當線程數已經達到最大的maximumPoolSizes時,再有新的元素嘗試加入ArrayBlockingQueue時會報錯。
喜歡這篇文章?歡迎打賞~~