java線程池

關於線程池的知識,自己找了相關的資料學習,整理一下。

線程池的作用:

     線程池作用就是限制系統中執行線程的數量。
     根據系統的環境情況,可以自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制線程數量,其他線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務需要運行時,如果線程池中有等待的工作線程,就可以開始運行了;否則進入等待隊列。

爲什麼要用線程池:

  1. 減少了創建和銷燬線程的次數,每個工作線程都可以被重複利用,可執行多個任務
  2. 可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因爲因爲消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)

線程池類

  1. package com.tdt.impl.ls; 
  2.  
  3. import java.util.LinkedList; 
  4.  
  5. /**
  6. * @project LocationGateway
  7. * @author sunnylocus  
  8. * @verson 1.0.0
  9. * @date   Aug 2, 2008
  10. * @jdk    1.4.2
  11. */ 
  12. publicclass ThreadPoolextends ThreadGroup { 
  13.     private boolean isClosed =false//線程池是否關閉 
  14.     private LinkedList workQueue;      //工作隊列 
  15.     private static int threadPoolID =1//線程池的id 
  16.     public ThreadPool(int poolSize) { //poolSize 表示線程池中的工作線程的數量 
  17.  
  18.         super(threadPoolID + "");     //指定ThreadGroup的名稱 
  19.         setDaemon(true);              //繼承到的方法,設置是否守護線程池 
  20.         workQueue =new LinkedList(); //創建工作隊列 
  21.         for(int i = 0; i < poolSize; i++) { 
  22.             new WorkThread(i).start();   //創建並啓動工作線程,線程池數量是多少就創建多少個工作線程 
  23.         } 
  24.     } 
  25.      
  26.     /** 向工作隊列中加入一個新任務,由工作線程去執行該任務*/ 
  27.     public synchronized void execute(Runnable task) { 
  28.         if(isClosed) { 
  29.             throw new IllegalStateException(); 
  30.         } 
  31.         if(task != null) { 
  32.             workQueue.add(task);//向隊列中加入一個任務 
  33.             notify();          //喚醒一個正在getTask()方法中待任務的工作線程 
  34.         } 
  35.     } 
  36.      
  37.     /** 從工作隊列中取出一個任務,工作線程會調用此方法*/ 
  38.     private synchronized Runnable getTask(int threadid)throws InterruptedException { 
  39.         while(workQueue.size() == 0) { 
  40.             if(isClosed) return null
  41.             System.out.println("工作線程"+threadid+"等待任務..."); 
  42.             wait();            //如果工作隊列中沒有任務,就等待任務 
  43.         } 
  44.         System.out.println("工作線程"+threadid+"開始執行任務..."); 
  45.         return (Runnable) workQueue.removeFirst(); //反回隊列中第一個元素,並從隊列中刪除 
  46.     } 
  47.      
  48.     /** 關閉線程池 */ 
  49.     public synchronized void closePool() { 
  50.         if(! isClosed) { 
  51.             waitFinish();       //等待工作線程執行完畢 
  52.             isClosed =true
  53.             workQueue.clear(); //清空工作隊列 
  54.             interrupt();       //中斷線程池中的所有的工作線程,此方法繼承自ThreadGroup類 
  55.         } 
  56.     } 
  57.      
  58.     /** 等待工作線程把所有任務執行完畢*/ 
  59.     public void waitFinish() { 
  60.         synchronized (this) { 
  61.             isClosed =true
  62.             notifyAll();           //喚醒所有還在getTask()方法中等待任務的工作線程 
  63.         } 
  64.         Thread[] threads =new Thread[activeCount()];//activeCount() 返回該線程組中活動線程的估計值。 
  65.         int count = enumerate(threads); //enumerate()方法繼承自ThreadGroup類,根據活動線程的估計值獲得線程組中當前所有活動的工作線程 
  66.         for(int i =0; i < count; i++) {//等待所有工作線程結束 
  67.             try
  68.                 threads[i].join(); //等待工作線程結束 
  69.             }catch(InterruptedException ex) { 
  70.                 ex.printStackTrace(); 
  71.             } 
  72.         } 
  73.     } 
  74.  
  75.     /**
  76.      * 內部類,工作線程,負責從工作隊列中取出任務,並執行
  77.      * @author sunnylocus
  78.      */ 
  79.     private class WorkThread extends Thread { 
  80.         private int id; 
  81.         public WorkThread(int id) { 
  82.             //父類構造方法,將線程加入到當前ThreadPool線程組中 
  83.             super(ThreadPool.this,id+""); 
  84.             this.id =id; 
  85.         } 
  86.         public void run() { 
  87.             while(! isInterrupted()) {  //isInterrupted()方法繼承自Thread類,判斷線程是否被中斷 
  88.                 Runnable task =null
  89.                try
  90.                     task = getTask(id);    //取出任務 
  91.                 }catch(InterruptedException ex) { 
  92.                     ex.printStackTrace(); 
  93.                 } 
  94.                //如果getTask()返回null或者線程執行getTask()時被中斷,則結束此線程 
  95.                if(task ==null)return
  96.                  
  97.                try
  98.                     task.run(); //運行任務 
  99.                 }catch(Throwable t) { 
  100.                     t.printStackTrace(); 
  101.                 } 
  102.             }//  end while 
  103.         }//  end run 
  104.     }// end workThread 
package com.tdt.impl.ls;

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.測試

  1. package com.tdt.test; 
  2.  
  3. import com.tdt.impl.ls.ThreadPool; 
  4.  
  5. publicclass ThreadPoolTest { 
  6.      
  7.     public static void main(String[] args)throws InterruptedException { 
  8.         ThreadPool threadPool =new ThreadPool(3);//創建一個有個3工作線程的線程池 
  9.         Thread.sleep(500);//休眠500毫秒,以便讓線程池中的工作線程全部運行 
  10.         //運行任務 
  11.         for (int i = 0; i <=5 ; i++) {//創建6個任務 
  12.             threadPool.execute(createTask(i)); 
  13.         } 
  14.         threadPool.waitFinish();//等待所有任務執行完畢 
  15.         threadPool.closePool();//關閉線程池 
  16.  
  17.     } 
  18.  
  19.     private static Runnable createTask(finalint taskID) { 
  20.         return new Runnable() { 
  21.             public void run() { 
  22.             //  System.out.println("Task" + taskID + "開始"); 
  23.                 System.out.println("Hello world"); 
  24.             //  System.out.println("Task" + taskID + "結束"); 
  25.             } 
  26.         }; 
  27.     } 
package com.tdt.test;

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 + "結束");
			}
		};
	}
}

結果:

  1. 工作線程0等待任務... 
  2. 工作線程1等待任務... 
  3. 工作線程2等待任務... 
  4.  
  5. 工作線程0開始執行任務... 
  6. Hello world 
  7. 工作線程0等待任務... 
  8.  
  9. 工作線程1開始執行任務... 
  10. Hello world 
  11. 工作線程1等待任務... 
  12.  
  13. 工作線程2開始執行任務... 
  14. Hello world 
  15. 工作線程2等待任務... 
  16.  
  17. 工作線程0開始執行任務... 
  18. Hello world 
  19. 工作線程0等待任務... 
  20.  
  21. 工作線程1開始執行任務... 
  22. Hello world 
  23. 工作線程1等待任務... 
  24.  
  25. 工作線程2開始執行任務... 
  26. Hello world 
  27. 工作線程2等待任務... 

 

發佈了27 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章