線程池是和數據庫連接池類似的一種池,而僅僅是把池裏的對象換成了線程。
核心思想:最主要就是複用的思想,把運行階段儘量拉長,對每個任務的到來,不是重複創建、銷燬,而是重複利用之前建立的線程來執行任務
線程池的作用:
在程序啓動的時候就創建若干線程來響應處理,他們被稱爲線程池,裏面的線程稱之爲工作線程。
1.降低資源損耗。通過重複利用已經創建好的線程來減少在創建新線程和銷燬的時候帶來的資源損耗
2.提高響應速度,當新任務到來時,可以立即執行,而不用等待新線程的建立
3.提高線程的可管理性
一個線程池的屬性起碼包括初始化線程數量、線程數組、任務隊列。初始化線程數量指線程池初始化創建的線程數,線程數組保存了線程池中的所有線程,任務隊列指添加到線程池中等待處理所有的任務。
執行如下圖所示,池中有兩個線程,池裏線程的工作就是不斷循環檢測任務隊列中是否有需要執行的任務,如果有,則處理並移出隊列;因爲普通線程的話就是執行完run方法之後就會被JVM的垃圾回收器所回收;循環檢測就避免了這種情況,使線程一直存活。
簡單實現:
public final class ThreadPool {
private final int workerThread_num;
private WorkerThread[] workerThreads;
private List<Runnable> taskQueue = new LinkedList<Runnable>();
private static ThreadPool threadPool;
public ThreadPool(int worker_num) {
this.workerThread_num = worker_num;
workerThreads = new WorkerThread[workerThread_num];
for (int i = 0; i < workerThread_num; i++) { // 啓動工作線程
workerThreads[i] = new WorkerThread();
workerThreads[i].start();
}
}
public void execute(Runnable task) {
synchronized(taskQueue){
taskQueue.add(task);
}
}
private class WorkerThread extends Thread {
public void run() {
Runnable r = null;
while (true) { // 循環監聽
synchronized (taskQueue) {
if (!taskQueue.isEmpty()) {
r = taskQueue.remove(0);
r.run(); // 執行任務
}
}
}
}
}
}
使用線程池時只需要實例化一個對象,構造函數就會創建相應數量的線程並啓動線程,啓動的線程開始無限循環檢測任務隊列,執行方法exe-cute()僅僅是把任務添加任務隊列中。