多線程(六)實戰--手寫簡單的線程池

1.什麼是線程池?爲什麼用使用它

1.降低資源的消耗,在之前做elasticsearch高級客戶端的開發的項目中,每一次創建與elasticsearch的連接都會花費不少的時間,大約是1-2秒左右,這樣的話,使用elastcisearch這樣的分佈式搜索服務器就沒有必要了。所以可以使用線程池來對連接進行優化,如能把創建好的連接保存在線程池裏,每一次需要調用的時候從線程池中取出連接,可以大幅度的節約時間,提高資源利用率。

2.實現一個簡單的線程池的demo案例。

package main;

import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class MyThreadPool2 {
	// 線程池中線程個數爲5
	private static int WORK_NUM = 5;
	// 隊列中的隊列任務爲100
	private static int TASK_COUNT = 100;

	// 工作線程組
	private WorkThread[] workThreads;

	// 任務隊列
	private BlockingQueue<Runnable> taskQueue = null;
	private final int worker_num;// 用戶構造這個線程池的時候希望啓用的線程組

	// 根據個數創建默認的線程池
	public MyThreadPool2() {
		this(WORK_NUM, TASK_COUNT);
	}

	@Override
	public String toString() {
		return "MyThreadPool2 [workThreads=" + Arrays.toString(workThreads) + ", taskQueue=" + taskQueue
				+ ", worker_num=" + worker_num + "]";
	}

	public MyThreadPool2(int worker_num, int taskCount) {
		if (WORK_NUM <= 0) {
			worker_num = WORK_NUM;
		}
		if (taskCount <= 0) {
			taskCount = TASK_COUNT;
		}
		this.worker_num = worker_num;
		taskQueue = new ArrayBlockingQueue<>(taskCount);

		workThreads = new WorkThread[worker_num];
		for (int i = 0; i < worker_num; i++) {
			workThreads[i]=new WorkThread();
	    	workThreads[i].stopWorker();
			workThreads[i].start();
		}

	}

	// 執行任務,把任務加入隊列中,什麼時候執行由線程池來決定
	public void execute(Runnable task) {
		try {
			taskQueue.put(task);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void destory()
	{
		System.out.println("ready close pool");
		for (int i=0;i<worker_num;i++)
		{
			workThreads[i].stopWorker();
			workThreads[i]=null;
		}
		taskQueue.clear();
		
	}
	

	/**
	 * 內部類,工作線程
	 * 
	 * @author xuyuanfeng
	 *
	 */
	private class WorkThread extends Thread {

		public WorkThread() {
			// TODO Auto-generated constructor stub
		}

		@Override
		public void run() {
			Runnable r = null;
			// 當前線程有沒有被終止
			while (!isInterrupted()) {
				try {
					r = taskQueue.take();
					if (r != null) {
						System.out.println(getId() + " ready exec:" + r);
						r.run();
					}
					r = null;
				} catch (InterruptedException e) {
					e.printStackTrace();
				} // 拿到任務

			}
		}

		//中斷線程
		public void stopWorker() {
			interrupt();
		}
	}

}
package main;

import java.util.Random;

public class Main {
	public static void main(String[] args) throws InterruptedException {

		MyThreadPool2 t = new MyThreadPool2(3, 0);
		t.execute(new MyThread("testA"));
		t.execute(new MyThread("testB"));
		t.execute(new MyThread("testC"));
		t.execute(new MyThread("testD"));
		t.execute(new MyThread("testE"));
		Thread.sleep(10000);
		t.destory();
		System.out.println(t.toString());

	}

	static class MyThread implements Runnable {
		private String name;
		private Random r = new Random();

		public MyThread(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		@Override
		public void run() {

			try {
				Thread.sleep(r.nextInt(1000) + 2000);
			} catch (InterruptedException e) {
                System.out.println("線程斷開了");
//				e.printStackTrace();
			}
			System.out.println("任務" + name + "完成");

		}

	}

}

測試結果

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