java-線程池(一)

性能優化中,其中一塊是線程池的使用,初探線程池,從簡單瞭解到源碼分析,深入理解才能合理運用。


(一)線程池的來源及優點

單個異步任務,每次都需創建線程、銷燬線程,當任務處理的時間短而請求數卻巨大時,將導致資源消耗過多。

比如,數據庫連接,需消耗大量資源,建立線程池能重用數據庫訪問線程。


使用線程池的優點:

1.降低資源消耗。重用現有線程,減少線程創建銷燬開銷。

2.提高響應速度。任務啓動,無需經歷線程創建,速度提升。

3.線程控制性強。如定時、定期、單線程設置等。


(二)線程池類別

四種線程池類型:

1.newCachedThreadPool

有緩存的線程池,適用於大量短期任務


2.newFixedThreadPool 

定長的線程池,可控制最大線程併發數


3.newScheduledThreadPool 

定長的線程池,可定時和週期性執行線程


4.newSingleThreadExecutor 

單線程的線程池,保證所有任務按順序執行


(三)線程池類別實例分析


1.newCachedThreadPool

   private void newCacheThreadPool() {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            final int index = i;
            try {
                if (i == 1 || i == 3) {
                    Thread.sleep(100);
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            threadPool.execute(new Runnable() {


                @Override
                public void run() {
                    System.out.println("new cached thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
運行結果:

new cached thread pool 0:9
new cached thread pool 1:9
new cached thread pool 2:10
new cached thread pool 3:10
new cached thread pool 4:9
例子分析:因爲1和3線程休息了一下,等待其他線程執行完,所以重用了舊有的線程。


2.newFixedThreadPool 

   private void newFixedThreadPool() {
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println("new fixed thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
運行結果:

new fixed thread pool 0:9
new fixed thread pool 1:10
new fixed thread pool 2:9
new fixed thread pool 4:9
new fixed thread pool 3:10
例子分析:定長爲2,其他線程進入隊列,等待前倆線程執行完才運行。

3.newScheduledThreadPool 

    private void newScheduledThreadPool() {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(2);
        try {
            Thread.sleep(100);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadPool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                System.out.println("new scheduled thread pool :" + Thread.currentThread().getId());
            }
        }, 1, 3, TimeUnit.SECONDS);
    }
運行結果:

new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
new scheduled thread pool :9
例子分析:延遲1秒開始,每隔3秒運行一次。


4.newSingleThreadExecutor 

    private void newSingleThreadPool() {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println("new single thread pool " + index + ":" +
                        Thread.currentThread().getId());
                }
            });
        }
    }
運行結果:

new single thread pool 0:9
new single thread pool 1:9
new single thread pool 2:9
new single thread pool 3:9
new single thread pool 4:9

例子分析:只有單線程,所以,每次只能執行一個線程,其餘任務等待狀態。


一般來說,CachedTheadPool在程序執行過程中通常會創建與所需數量相同的線程,然後在它回收舊線程時停止創建新線程,因此它是合理的Executor的首選,只有當這種方式會引發問題時(比如需要大量長時間面向連接的線程時),才需要考慮用FixedThreadPool。(該段話摘自《Thinking in Java》第四版)


線程池源碼分析請看java-線程池(二)


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