线程池的实现
通常情况下。server软件会同一时候接纳并服务多个用户。当客户请求到达时,server主线程会创建一个工作者线程代表server为这个客户服务。当用户不须要服务的时候,线程结束,并释放创建线程用到的全部资源。
当下一个请求到达的时候,server又会创建一个新的线程为之服务。
可是因为创建线程须要非常多资源。包含处理器、内存等,这个过程在重复的创建线程中浪费了大量的处理器时间。尤其在大量并发客户的情况下,server对应会特别缓慢。这个时候就能够考虑用线程池。
线程池中先预留有一定数量的的线程。当有须要的时候,server就会从线程池中取出一个工作者线程,将任务赋给线程。当工作者线程运行完任务之后。它将会被又一次放回线程池中。注意,任务一般是指一个实现接口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; } } } } }