多線程——newCachedThreadPool線程池


newCachedThreadPool線程池:

理解:
  1).newCachedThreadPool可以創建一個無限大小的線程池(實際上是一個可緩存線程池)。
      可以通過Executors的靜態方法創建線程池:
        public static ExecutorService newCachedThreadPool() 或者
         public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) 。
  2).返回的是ExecutorService對象線程池。
  3).newCachedThreadPool在執行過程中通常會創建與所需數量相同的線程,然后在它回收舊線程時停止創建新線程,因此它是合理的Executor的首選。
     只有當這種方式會引發問題時(內存溢出),你才需要切換到newFixedThreadPool()。
  4).無限制不代表不可以復用線程,假設說一開始進來10個任務,啟動了10個線程,10個任務結束后,然后又來了5個任務(線程還沒被回收),
      這時候會復用之前的線程,不會新起線程,這就達到了使用“線程池”的意義。
使用場景:
  1. 耗時較短的任務。
  2. 任務處理速度 > 任務提交速度 ,這樣才能保證不會不斷創建新的進程,避免內存被占滿。
//首先看Executors中通過newCachedThreadPool創建線程池的方法的源碼
//此方法是通過new一個ThreadPoolExecutor來創建的
//這個構造方法有5個參數:
//第一個參數corePoolSize(核心池大小)為0,
//第二個參數maximumPoolSize(最大線程池大小)為Integer.MAX_VALUE無限大,源碼中是:public static final int   MAX_VALUE = 0x7fffffff;
//第三個參數keepAliveTime(線程存貨的時間)是60秒,意味着線程空閑時間超過60秒就會被殺死。
//第五個參數采用SynchronousQueue裝等待的任務,這個阻塞隊列沒有存儲空間,這意味着只要有請求到來,就必須要找到一條工作線程處理他,
//    如果當前沒有空閑的線程,那么就會再創建一條新的線程。
public class Executors {   
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
}

//ThreadPoolExecutor類中此構造函數源碼:
public class ThreadPoolExecutor extends AbstractExecutorService {
      public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
    }
}

 

下面是Thinking in java書中的例子:
public class LiftOff implements Runnable {
    protected int countDown = 5;
    private static int taskCount = 0;
    private final int id = taskCount++;

    public LiftOff() {
    }

    public LiftOff(int countDown) {
        this.countDown = countDown;
    }

    public String status() {
        return "# " + id + " ( " + (countDown > 0 ? countDown : "LiftOff !") + " )";
    }

    @Override
    public void run() {
        while (countDown-- > 0) {
            System.out.println(status());
            Thread.yield();
        }
    }
}
public class CachedThreadPool {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executorService.execute(new LiftOff());
        }
    }
}
結果:
# 2 ( 4 )
# 0 ( 4 )
# 1 ( 4 )
# 2 ( 3 )
# 0 ( 3 )
# 2 ( 2 )
# 1 ( 3 )
# 2 ( 1 )
# 0 ( 2 )
# 2 ( LiftOff ! )
# 1 ( 2 )
# 0 ( 1 )
# 1 ( 1 )
# 0 ( LiftOff ! )
# 1 ( LiftOff ! )

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM