java 模擬線程池

前兩天從師傅那學了一個模擬線程池的方法,覺得很有用,務必得記錄一下。

首先說一下對線程池的理解及它的優點:

線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然後在創建線程後自動啓動這些任務。

在面向對象編程中,創建和銷燬對象是很費時間的,因爲創建一個對象要獲取內存資源或者其它更多

資源。在Java中更是如此,虛擬機將試圖跟蹤每一個對象,以便能夠在對象銷燬後進行垃圾回收。所

以提高服務程序效率的一個手段就是儘可能減少創建和銷燬對象的次數,特別是一些很耗資源的對象

創建和銷燬。

那麼,線程池的優點:

第一:降低資源消耗。通過重複利用已創建的線程降低線程創建和銷燬造成的消耗。

第二:提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行。

第三:提高線程的可管理性。

 

接下來通過代碼演示線程池,我們從創建任務開始,將任務分配到線程池中執行這些任務。

首先創建一個任務類,

package ThreadPool;
/**
 * @author 趙璽
 *用runnable線程創建任務
 */
public class Task implements Runnable{
	//重寫run方法
	public void run() {
		//獲取當前可執行線程的名字
		String name = Thread.currentThread().getName();
		System.out.println(name+"任務正在執行中......");
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name+"任務執行完畢");
		
	}
	
}

 

模擬線程池,

package ThreadPool;

import java.util.List;
import java.util.ArrayList;

/**
 * 線程池的實現
 * @author 趙璽
 * @param <ThreadWorker>
 *
 */
public class ThreadPool{

	//初始化線程數量
	private int count;
	//保存工作的線程數組
	private ThreadWorker[] pool;
	//保存任務的隊列
	private List<Runnable> task_list = new ArrayList<Runnable>();
	
	public ThreadPool(int count){
		this.count = count;
		pool = new ThreadWorker[this.count];
		for(int i=0;i<this.count;i++){
			ThreadWorker worker = new ThreadWorker();
			pool[i] = worker;
			pool[i].setName(i+"號線程");
			pool[i].start();
			System.out.println("第"+pool[i].getName()+"已就緒,等待執行任務。。。");
		}
		System.out.println("線程初始化完畢");
		
	}
	
	//執行任務
	public void execute(Runnable task){
		synchronized(task_list){
			//添加到任務隊列
			task_list.add(task);
			//通知
			task_list.notify();
		}
	}
	
	//工作線程類
	private class ThreadWorker extends Thread{
		
		public void run(){
			Runnable r;
			while(true){
				synchronized(task_list){
					if(task_list.isEmpty()){//任務隊列中沒有任務,等待
						try {
							task_list.wait();//等待
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					//有任務,執行
					r = task_list.remove(0);
				}
				r.run();//執行
			}
		}
	}
	//主方法
	public static void main(String[] args) {
		//創建一個線程池對象
		ThreadPool threadpool = new ThreadPool(5);
		//創建20個任務對象
		for(int i=0;i<20;i++){
			Task task = new Task();
			threadpool.execute(task);
		}
		
	}
	
}

 

系統線程池,

package ThreadPool;
/**
 * 測試類
 * 使用系統的線程池
 */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
	//主方法
	public static void main(String[] args) {
		//創建一個固定線程集合的線程池
		ExecutorService pool = Executors.newFixedThreadPool(5);
		//創建20個任務
		for(int i=0;i<20;i++){
			Task task = new Task();
			pool.execute(task);
		}
		//啓動一次順序關閉線程池
		pool.shutdown();
		
	}
	
}

 

模擬線程池執行結果:

第0號線程已就緒,等待執行任務。。。
第1號線程已就緒,等待執行任務。。。
第2號線程已就緒,等待執行任務。。。
第3號線程已就緒,等待執行任務。。。
第4號線程已就緒,等待執行任務。。。
線程初始化完畢
0號線程任務正在執行中......
4號線程任務正在執行中......
1號線程任務正在執行中......
2號線程任務正在執行中......
3號線程任務正在執行中......
0號線程任務執行完畢
0號線程任務正在執行中......
2號線程任務執行完畢
2號線程任務正在執行中......
4號線程任務執行完畢
4號線程任務正在執行中......
3號線程任務執行完畢
3號線程任務正在執行中......
1號線程任務執行完畢
1號線程任務正在執行中......
0號線程任務執行完畢
0號線程任務正在執行中......
4號線程任務執行完畢
4號線程任務正在執行中......
3號線程任務執行完畢
3號線程任務正在執行中......
1號線程任務執行完畢
1號線程任務正在執行中......
2號線程任務執行完畢
2號線程任務正在執行中......
0號線程任務執行完畢
0號線程任務正在執行中......
3號線程任務執行完畢
4號線程任務執行完畢
4號線程任務正在執行中......
2號線程任務執行完畢
2號線程任務正在執行中......
3號線程任務正在執行中......
1號線程任務執行完畢
1號線程任務正在執行中......
0號線程任務執行完畢
1號線程任務執行完畢
3號線程任務執行完畢
4號線程任務執行完畢
2號線程任務執行完畢

 

系統線程池執行結果:
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-4任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-3任務執行完畢
pool-1-thread-5任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-2任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-4任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-3任務執行完畢
pool-1-thread-5任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-2任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-4任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-1任務正在執行中......
pool-1-thread-3任務執行完畢
pool-1-thread-3任務正在執行中......
pool-1-thread-5任務執行完畢
pool-1-thread-5任務正在執行中......
pool-1-thread-4任務執行完畢
pool-1-thread-4任務正在執行中......
pool-1-thread-2任務執行完畢
pool-1-thread-2任務正在執行中......
pool-1-thread-1任務執行完畢
pool-1-thread-3任務執行完畢
pool-1-thread-5任務執行完畢
pool-1-thread-4任務執行完畢
pool-1-thread-2任務執行完畢

從結果可以看出模擬的線程池也能達到效果。

模擬線程池的核心是ThreadWorker類,在線城池初始化完畢後,只需在execute()方法中給任務隊列加上

synchornized同步鎖即可。

在這裏分析一下newFixedThreadPool()方法,下面是api上的解釋:

newFixedThreadPool(int nThreads)
創建一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程。

FixedThreadPool
是一個典型且優秀的線程池,它具有線程池提高程序效率和節省創建線程時所耗的開銷
的優點。但是,在線程池空閒時,即線程池中沒有可運行任務時,它不會釋放工作線程
,還會佔用一定的系統資源。

但在這裏得說一下shutdown()方法:啓動一次順序關閉,執行以前提交的任務,但不接受新任務。如果已經

關閉,則調用沒有其他作用。所以,用系統地線程池調用shutdown()方法之後會關閉線程池,而模擬的線程池不會。

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章