線程池的作用:
線程池作用就是限制系統中執行線程的數量。
根據系統的環境情況,可以自動或 手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制 線程數量,其他線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等 待進程,線程池的這一資源處於等待。當一個新任務需要運行時,如果線程池中有等待的工作線程,就可以開 始運行了;否則進入等待隊列。
為什麼要用線程池:
減少了創建和銷毀線程的次數,每個工作 線程都可以被重復利用,可執行多個任務
可以根據系統的承受能力,調整線程池中工作線線程的數目 ,防止因為因為消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存 也就越大,最後死機)
線程池類
import java.util.LinkedList; /** * @project LocationGateway * @author sunnylocus * @verson 1.0.0 * @date Aug 2, 2008 * @jdk 1.4.2 */ public class ThreadPool extends ThreadGroup { private boolean isClosed = false; //線程池是否關閉 private LinkedList workQueue; //工作隊列 private static int threadPoolID = 1; //線程池的id public ThreadPool(int poolSize) { //poolSize 表示線程池中的工作線程的數量 super(threadPoolID + ""); //指定ThreadGroup的名稱 setDaemon(true); //繼承到的方法,設置是否守護線程池 workQueue = new LinkedList(); //創建工作隊列 for(int i = 0; i < poolSize; i++) { new WorkThread(i).start(); //創建並啟動工作線程,線程池數量是多少就創建多少個工作線 程 } } /** 向工作隊列中加入一個新任務,由工作線程去執行該任務*/ public synchronized void execute(Runnable task) { if(isClosed) { throw new IllegalStateException(); } if(task != null) { workQueue.add(task);//向隊列中加入一個任務 notify(); //喚醒一個正在getTask()方法中待任務的工作線程 } } /** 從工作隊列中取出一個任務,工作線程會調用此方法*/ private synchronized Runnable getTask(int threadid) throws InterruptedException { while(workQueue.size() == 0) { if(isClosed) return null; System.out.println("工作線程"+threadid+"等待任務..."); wait(); //如果工作隊列中沒有任務,就等待任務 } System.out.println("工作線程"+threadid+"開始執行任務..."); return (Runnable) workQueue.removeFirst(); //反回隊列中第一個元素,並從隊列中刪除 } /** 關閉線程池 */ public synchronized void closePool() { if(! isClosed) { waitFinish(); //等待工作線程執行完畢 isClosed = true; workQueue.clear(); //清空工作隊列 interrupt(); //中斷線程池中的所有的工作線程,此方法繼承自ThreadGroup類 } } /** 等待工作線程把所有任務執行完畢*/ public void waitFinish() { synchronized (this) { isClosed = true; notifyAll(); //喚醒所有還在getTask()方法中等待任務的工作線程 } Thread[] threads = new Thread[activeCount()]; //activeCount() 返回該線程組中活動線程的估 計值。 int count = enumerate(threads); //enumerate()方法繼承自ThreadGroup類,根據活動線程的估計 值獲得線程組中當前所有活動的工作線程 for(int i =0; i < count; i++) { //等待所有工作線程結束 try { threads[i].join(); //等待工作線程結束 }catch(InterruptedException ex) { ex.printStackTrace(); } } } /** * 內部類,工作線程,負責從工作隊列中取出任務,並執行 * @author sunnylocus */ private class WorkThread extends Thread { private int id; public WorkThread(int id) { //父類構造方法,將線程加入到當前ThreadPool線程組中 super(ThreadPool.this,id+""); this.id =id; } public void run() { while(! isInterrupted()) { //isInterrupted()方法繼承自Thread類,判斷線程是否被中斷 Runnable task = null; try { task = getTask(id); //取出任務 }catch(InterruptedException ex) { ex.printStackTrace(); } //如果getTask()返回null或者線程執行getTask()時被中斷,則結束此線程 if(task == null) return; try { task.run(); //運行任務 }catch(Throwable t) { t.printStackTrace(); } }// end while }// end run }// end workThread }
2.測試類
import com.tdt.impl.ls.ThreadPool; public class ThreadPoolTest { public static void main(String[] args) throws InterruptedException { ThreadPool threadPool = new ThreadPool(3); //創建一個有個3工作線程的線程池 Thread.sleep(500); //休眠500毫秒,以便讓線程池中的工作線程全部運行 //運行任務 for (int i = 0; i <=5 ; i++) { //創建6個任務 threadPool.execute(createTask(i)); } threadPool.waitFinish(); //等待所有任務執行完畢 threadPool.closePool(); //關閉線程池 } private static Runnable createTask(final int taskID) { return new Runnable() { public void run() { // System.out.println("Task" + taskID + "開始"); System.out.println("Hello world"); // System.out.println("Task" + taskID + "結束"); } }; } }
結果:
工作線程0等待任務... 工作線程1等待任務... 工作線程2等待任務... 工作線程0開始執行任務... Hello world 工作線程0等待任務... 工作線程1開始執行任務... Hello world 工作線程1等待任務... 工作線程2開始執行任務... Hello world 工作線程2等待任務... 工作線程0開始執行任務... Hello world 工作線程0等待任務... 工作線程1開始執行任務... Hello world 工作線程1等待任務... 工作線程2開始執行任務... Hello world 工作線程2等待任務...