1、線程池簡介
- 爲了不繫統頻繁的建立和銷燬線程,咱們能夠將建立的線程進行復用。數據庫中的數據庫鏈接池也是此意。Java中的線程池是運用場景最多的併發框架,幾乎全部須要異步或併發執行任務的程序均可以使用線程池。在開發過程當中,合理地使用線程池可以帶來如下好處:
- 第一:下降資源消耗。經過重複利用已建立的線程下降線程建立和銷燬形成的消耗。
- 第二:提升響應速度。當任務到達時,任務能夠不須要等到線程建立就能當即執行。
- 第三:提升線程的可管理性。線程是稀缺資源,若是無限制地建立,不只會消耗系統資源,還會下降系統的穩定性,使用線程池能夠進行統一分配、調優和監控。可是,要作到合理利用線程池,必須對其實現原理了如指掌。
- 在線程池中總有那麼幾個活躍的線程,也有必定的最大值限制,一個業務使用完線程以後,不是當即銷燬而是將其放入到線程池中,從而實現線程的複用。簡而言之:建立線程變成了從線程池獲取空閒的線程,關閉線程變成了向池子中歸還線程。
2、JDK對線程池的支持
- 爲了更好的控制多線程,JDK提供了一套線程框架Executor,幫助開發人員有效的進行線程控制。他們都在java.util.concurrent包中,時JDK併發包的核心。其中一個比較重要的類:Executors,扮演者線程工廠的角色,咱們經過Executors能夠建立特定功能的線程池。 Executors建立線程池的方法:
- newFixedThreadPool()方法,該方法返回一個固定數量的線程池,該方法的線程數始終不變,當有一個任務提交時,若線程池中空閒,則當即執行,若沒有,則會被暫緩在一個任務隊列中等待有空閒的線程去執行。
- newSingleThreadExecutor()方法,建立一個線程的線程池,若空閒則執行,若沒有空閒則暫緩在任務隊列中。
- newCachedThreadPool()方法,返回一個可根據實際狀況調整線程個數的線程池,不限制最大線程數量,若用空閒的線程則執行任務,若無則不建立線程。而且每個空閒線程會在60秒後自動回收。 4.newScheduledThreadPool()方法,該方法返回一個SchededExecutorService對象,但該線程池能夠指定線程的數量。
- 注:以上4中方法的本質內部底層都是實際建立的都是一個ThreadPoolExecutor對象,只是對ThreadPoolExecutor構造方法,進行了默認值的設定。
- 所以,在以上方法不足以供咱們使用時,能夠本身定義線程池,構造方法以下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {…}
- corePoolSize 核心線程數(表示線程池初始化的時候就存在多少個線程);
- maximumPoolSize 線程池最大容量大小;
- keepAliveTime 線程池空閒時,線程存活的時間;
- TimeUnit 時間單位;
- ThreadFactory 線程工廠;
- BlockingQueue任務隊列(線程數大於線程池中線程的數量發佈放入的隊列);
- RejectedExecutionHandler 線程拒絕策略;(例如線程池中有兩個線程,若這兩個線程都被佔用第3個線程來了能夠設定拒絕策略拒絕這個線程)
2.1 newCachedThreadPool(實現定時任務)
package com.rrss.test.thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class Task extends Thread {
public void run() {
System.out.println("run");
}
}
public class ThreadPoolDemo {
public static void main(String[] args) {
Task task = new Task();
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
scheduled.scheduleWithFixedDelay(task, 3, 1, TimeUnit.SECONDS);// task在啓動3s後,每隔1秒執行一次
}
}