線程池
為什麼要使用線程池?
線程的建立、銷毀會增加系統資源的開銷,程式性能的降低。
為了避免頻繁的建立、銷毀資源。我們可以建立一個池子,裡面放着 N 個線程,需要使用線程則可以從線程池裡邊擷取,使用完畢後将線程再放回線程池中以便達到線程的重用。
線程池的原理
舉例:
線程池裡邊配置設定 3個線程,當有4個任務需要執行時,先配置設定 3個線程去執行任務,第4個任務等待,直到3個線程中的某個線程中的任務執行完畢後,空閑的線程重新回到線程池,此時再講任務4配置設定給空閑的線程去執行。
将任務送出給線程池,由線程池配置設定線程、運作任務,并在目前任務結束後複用線程。
建立線程池
常用的線程池接口和類
- Executor :線程池頂級接口
- ExecutorService :線程池接口, 通過 submit(Runnable task)送出任務
- Executors :工廠類,通過此類可以擷取一個線程池
Executors 類
newFixedThreadPool(int nThreads) 方法,擷取固定數量線程池
newCachedThreadPool 方法, 動态擷取數量的線程池, 如不夠則新建立,沒有上限
線程池基本使用1
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadDemo2 {
public static void main(String[] args) {
// 1. 建立線程池
ExecutorService es = Executors.newFixedThreadPool(4);
// 2. 建立任務
Runnable r = new Runnable() {
private int ticker = 100;
@Override
public void run() {
while (true) {
if (ticker <= 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "賣了第 " + ticker + "張票");
ticker--;
}
}
};
// 3. 送出任務
for (int i = 0; i < 4; i++) {
es.submit(r);
}
// 4. 關閉線程池 shutdown方法等待所有任務執行完畢後關閉線程池, 而 shutdownNow方法不等待任務執行完畢,直接關閉線程池
es.shutdown();
}
}
補充:
Executors.newFixedThreadPool(4) 建立固定個數的線程池;
Executors.newCachedThreadPool(); 建立緩沖線程池,線程數量根據任務決定。
Executors.newSingleThreadExecutor(); 建立單線程的線程池, 線程數量為1
Executors.newScheduledThreadPool(4); 建立排程線程的線程池