通常情况下,服务器软件会同时接纳并服务多个用户。当客户请求到达时,服务器主线程会创建一个工作者线程代表服务器为这个客户服务。当用户不需要服务的时候,线程结束,并释放创建线程用到的所有资源。当下一个请求到达的时候,服务器又会创建一个新的线程为之服务。
但是由于创建线程需要很多资源,包括处理器、内存等,这个过程在反复的创建线程中浪费了大量的处理器时间。尤其在大量并发客户的情况下,服务器相应会特别缓慢。这个时候就可以考虑用线程池。
线程池中先预留有一定数量的的线程,当有需要的时候,服务器就会从线程池中取出一个工作者线程,将任务赋给线程。当工作者线程执行完任务之后,它将会被重新放回线程池中。注意,任务通常是指一个实现接口runnable的类的实例。
但是由于创建线程需要很多资源,包括处理器、内存等,这个过程在反复的创建线程中浪费了大量的处理器时间。尤其在大量并发客户的情况下,服务器相应会特别缓慢。这个时候就可以考虑用线程池。
线程池中先预留有一定数量的的线程,当有需要的时候,服务器就会从线程池中取出一个工作者线程,将任务赋给线程。当工作者线程执行完任务之后,它将会被重新放回线程池中。注意,任务通常是指一个实现接口runnable的类的实例。
接下来,是一个简单线程池的实现:
public final class ThreadPool {
private static ThreadPool instance = ThreadPool.getInstance();
public static final int SYSTEM_BUSY_TASK_COUNT = 150; //系统繁忙的任务数
/* 默认池中线程数 */
public static int worker_num = 5;
/* 已经处理的任务数 */
private static int taskCounter = 0;
public static boolean systemIsBusy = false;
private static List<Task> taskQueue = Collections
.synchronizedList(new LinkedList<Task>());
/* 池中的所有线程 */
public PoolWorker[] workers;
private ThreadPool() {
workers = new PoolWorker[5];
for (int i = 0; i < workers.length; i++) {
workers[i] = new PoolWorker(i);
}
}
/*构造函数*/
private ThreadPool(int pool_worker_num) {
worker_num = pool_worker_num;
workers = new PoolWorker[worker_num];
for (int i = 0; i < workers.length; i++) {
workers[i] = new PoolWorker(i);
}
}
/*通过该函数得到线程池的实例*/
public static synchronized ThreadPool getInstance() {
if (instance == null)
return new ThreadPool();
return instance;
}
/**
* 增加新的任务
* 每增加一个新任务,都要唤醒任务队列
* @param newTask
*/
public void addTask(Task newTask) {
synchronized (taskQueue) {
newTask.setTaskId(++taskCounter);
newTask.setSubmitTime(new Date());
taskQueue.add(newTask);
/* 唤醒队列, 开始执行 */
taskQueue.notifyAll();
}
}
/**
* 批量增加新任务
* @param taskes
*/
public void batchAddTask(Task[] taskes) {
if (taskes == null || taskes.length == 0) {
return;
}
synchronized (taskQueue) {
for (int i = 0; i < taskes.length; i++) {
if (taskes[i] == null) {
continue;
}
taskes[i].setTaskId(++taskCounter);
taskes[i].setSubmitTime(new Date());
taskQueue.add(taskes[i]);
}
/* 唤醒队列, 开始执行 */
taskQueue.notifyAll();
}
for (int i = 0; i < taskes.length; i++) {
if (taskes[i] == null) {
continue;
}
}
}
/**
* 线程池信息
* @return
*/
public String getInfo() {
StringBuffer sb = new StringBuffer();
sb.append("\nTask Queue Size:" + taskQueue.size());
for (int i = 0; i < workers.length; i++) {
sb.append("\nWorker " + i + " is "
+ ((workers[i].isWaiting()) ? "Waiting." : "Running."));
}
return sb.toString();
}
/**
* 销毁线程池
*/
public synchronized void destroy() {
for (int i = 0; i < worker_num; i++) {
workers[i].stopWorker();
workers[i] = null;
}
taskQueue.clear();
}
/**
* 池中工作线程(线程池拥有多个线程对象)
*/
private class PoolWorker extends Thread {
private int index = -1;
/* 该工作线程是否有效 */
private boolean isRunning = true;
/* 该工作线程是否可以执行新任务 */
private boolean isWaiting = true;
/*构造函数*/
public PoolWorker(int index) {
this.index = index;
start();
}
public void stopWorker() {
this.isRunning = false;
}
public boolean isWaiting() {
return this.isWaiting;
}
/**
* 循环执行任务
* 这也许是线程池的关键所在
*/
public void run() {
while (isRunning) {
Task task = null;
synchronized (taskQueue) {
while (taskQueue.isEmpty()) {
try {
/* 任务队列为空,则等待有新任务加入从而被唤醒 */
taskQueue.wait(20);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
/* 取出任务执行 */
task = (Task) taskQueue.remove(0);
}
if (task != null) {
isWaiting = false;
try {
/* 该任务是否需要立即执行 */
if (task.needExecuteImmediate()) {
new Thread(task).start(); //开启新线程执行这个Task
} else {
System.out.println("一个任务正在执行");
task.run(); //执行这个Task的是同一个线程
}
} catch (Exception e) {
e.printStackTrace();
}
isWaiting = true;
task = null;
}
}
}
}
}