Java默認提供的線程池


Java的線程池都是通過ThreadPoolExecutor來構建。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

在Executors工廠類中,Java默認提供了四種類型的線程池。

FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

這個線程池的特點:

  • 這是一種線程數量固定的線程池,因為corePoolSize和maximunPoolSize都為用戶設定的線程數量nThreads;
  • keepAliveTime為0,意味着一旦有多余的空閑線程,就會被立即停止掉,不過因為最多只有nThreads個線程,且corePoolSize和maximunPoolSize值一致,所以這個值無法發揮作用;
  • 阻塞隊列采用了LinkedBlockingQueue,它是一個無界隊列,由於阻塞隊列是一個無界隊列,因此永遠不可能拒絕任務。

212219343783699

CachedThreadPool

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
這個線程池的特點
  • 這是一個線程數量可以“無限”擴大(不能超過整型最大值)的線程池;
  • 比較適合處理執行時間比較小的任務;
  • corePoolSize為0,maximumPoolSize為無限大,意味着線程數量可以無限大;
  • keepAliveTime為60S,意味着線程空閑時間超過60S就會被殺死;
  • 采用SynchronousQueue裝等待的任務,這個阻塞隊列沒有存儲空間,這意味着只要有請求到來,就必須要找到一條工作線程處理他,如果當前沒有空閑的線程,那么就會再創建一條新的線程。

v2-f9cff0865c6143ace452274046322335_hd

SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

這個線程池的特點:

  • 只有一個線程,使用了無界隊列LinkedBlockingQueue,某種意義上等同於newFixedThreadPool(1);
  • 因為只有一個線程,所以能夠保證所有任務是FIFO地執行。

v2-ff4708ec83b9f65efca3225a19a1921d_hd

ScheduledThreadPool

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

ScheduledThreadPoolExecutor繼承自ThreadPoolExecutor。

這個線程池的特點:

它接收SchduledFutureTask類型的任務,有兩種提交任務的方式:

  • scheduledAtFixedRate
  • scheduledWithFixedDelay

從提交方式可以看出,這個線程池主要處理定時任務或延時任務。

SchduledFutureTask接收的參數:

  • time:任務開始的時間s
  • equenceNumber:任務的序號
  • period:任務執行的時間間隔

它采用DelayQueue存儲等待的任務:

  • DelayQueue內部封裝了一個PriorityQueue,它會根據time的先后時間排序,若time相同則根據sequenceNumber排序;
  • DelayQueue也是一個無界隊列;

工作線程的執行過程:

  • 工作線程會從DelayQueue取已經到期的任務去執行;
  • 執行結束后重新設置任務的到期時間,再次放回DelayQueue

v2-6525fe2330e34ec0936e4a76782b560b_hd

#########


免責聲明!

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



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