1. 程式人生 > >Java多線程系列——線程池簡介

Java多線程系列——線程池簡介

銷毀 lis trac thread 時間 style rup 結果 del

什麽是線程池?

為了避免系統頻繁地創建和銷毀線程,我們可以讓創建的線程進行復用。
用線程時從線程池中獲取,用完以後不銷毀線程,而是歸還給線程池。

JDK 對線程池的支持

為了更好的控制多線程,JDK 提供了一套線程池框架,結構如下圖所示

技術分享

它們都在 java.util.concurrent 包中。

  • Executor 用來執行任務,它提供了 execute() 方法來執行 Runnable 任務;
  • ThreadPoolExecutor 表示一個線程池;
  • Executors 它是一個靜態工廠工廠類,通過它可以取得一個擁有特定功能的線程池;

不同特性的線程池

  1. newFixedThreadPool()
    :返回固定數量的線程池。線程池中的數量始終不變。當有新任務提交時,線程池中若有空閑線程,則立即執行。若沒有則放入任務隊列中,等待有空閑線程時,處理任務隊列中的任務。
  2. newSingleThreadPool():返回只有一個線程的線程池。若有多余一個任務被提交,則放入任務隊列中,等待有空閑線程時,按先入先出的順序執行隊列中的任務。
  3. newCachedThreadPool():返回一個可根據實際情況調整線程數量的線程池。這個方法創建出來的線程池可以被無線擴展,並且當需求降低時會自動收縮。
  4. newSingleThreadScheduledExecutor():返回一個 ScheduledExecutorService 對象,線程池大小為 1。ScheduledExecutorService 接口在 ExecutorService 接口之上擴展了在給定時間執行某任務的功能,在某個固定時間延遲之後,或周期性執行某個任務。
  5. newScheduledThreadPool():返回一個 ScheduledExecutorService 對象,並可指定線程數量。
  6. ScheduledExecutorService 並不一定會立即安排執行任務,而是起到了計劃任務的作用。
  7. 它主要有一下三個方法:
    1. schedule():會在給定的時間,對任務進行一次調度
    2. scheduleAtFixedRate():創建並執行一個在給定初始延遲後首次啟用的定期操作,後續操作具有給定的周期
    3. scheduleWithFixedDelay():創建並執行一個在給定初始延遲後首次啟用的定期操作,隨後,在每一次執行終止和下一次執行開始之間都存在給定的延遲

示例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by zhengbin on 2017/10/24
 */
public class ExecutorServiceTest {
    private static class Task implements Runnable {
    public void run() {
            System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Task t = new Task();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10;i++) {
            executorService.execute(t);
        }
        executorService.shutdown();
    }
}

運行結果

1509258535474:Thread ID:11
1509258535474:Thread ID:12
1509258535475:Thread ID:14
1509258535475:Thread ID:15
1509258535475:Thread ID:13
1509258536475:Thread ID:15
1509258536475:Thread ID:11
1509258536475:Thread ID:12
1509258536475:Thread ID:14
1509258536475:Thread ID:13

結果說明

主線程創建了一個固定大小的線程池,線程池的容量是 5。

運行結果輸出了運行的時間戳,可以看到,前 5 個任務執行的時間戳與後 5 個任務的時間戳相差了 1000 毫秒。

這說明在這 10 個任務中,是分成 2 批次執行的。這也完全符合一個只有 5 個線程的線程池的行為。

當把線程池改為 newCachedThreadPool() 時,就會將 10 個任務同時執行。

Java多線程系列——線程池簡介