線程池ExecutorService 中併發數的(引入信號量Semaphore)控制執行

查看本機處理器的核心數代碼:Runtime.getRuntime().availableProcessors()
所以,應用程序的最小線程數應該等於可用的處理器核數。如果所有的任務都是計算密集型的,則創建處理器可用的核心數那麼多線程就可以了。在這種情況下,創建更多的線程對程序性能而言反而是不利的。因爲當有多個任務處於就緒狀態時,處理器核心需要在線程間頻繁進行上下文切換,而這種切換對程序性能損耗較大。但如果任務都是IO密集型的,那麼我們就需要開更多的線程來提高性能。

當一個任務執行IO操作時,其線程將被阻塞,於是處理器可以立即進行上下文的切換以便處理其他就緒線程。如果我們只有處理可用核心數那麼多個線程的話,則即使有待執行的任務也無法處理,因爲我們已經拿不出更多的線程供處理器調度了。

如果任務有50%的時間處於阻塞狀態,則程序所需線程數爲處理器可用核心數的兩倍。如果任務被阻塞的時間少於50%,即這些任務是計算密集型的,則程序所需線程數將隨之減少,但最少也不應低於處理器的核心數。如果任務被阻塞的時間大於執行時間,即該任務是IO密集型的,我們就需要創建比處理器核心數大幾倍數量的線程。

線程數=CPU可用核心數/(1-阻塞係數),其中阻塞係數取值0和1之間。
計算密集型任務阻塞係數爲0,而IO密集型任務的阻塞係數接近1。
廢話,不多說了哈!直接上代碼:

package zl;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
 *  Semaphore還提供一些其他方法:
    int availablePermits() :返回此信號量中當前可用的許可證數。
    int getQueueLength():返回正在等待獲取許可證的線程數。
    boolean hasQueuedThreads() :是否有線程正在等待獲取許可證。
    void reducePermits(int reduction) :減少reduction個許可證。是個protected方法。
    Collection getQueuedThreads() :返回所有等待獲取許可證的線程集合。是個protected方法。
    tryAcquire()方法嘗試獲取許可證
 * @author ZL
 *  2017年11月26日
 */
public class SemaphoreTest {
    private static final int THREAD_COUNT = 30;//總共的線程數
    private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
    private static Semaphore semaphore = new Semaphore(10);//可以併發執行的線程數

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            final int j=i;
            threadPool.execute(new Runnable() {
                public void run() {
                    try {
                        semaphore.acquire();//acquire()獲取一個許可證
                        /**
                         * 要執行的代碼塊
                         */
                        System.out.println(j+"zl");
                        semaphore.release();//使用完之後調用release()歸還許可證
                    } catch (InterruptedException e) {
                    }
                }
            });
        }
        threadPool.shutdown();

    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章