最近写了一个 HTTP 代理服务器,发现访问网页时建立的连接很多,消耗的线程也非常的多,对于系统是
一个不小的开销.而且这些线程存在的时间都很短,99%以上的线程存在的时间都在毫秒的等级,相对来说
线程的建立的注销就占了绝大部分的CPU时间. 因此,在网上搜了一下线程池的资料,发现里面的东西不是太大太复杂,就是写得太烂,根本没有一点专业
水准. 没办法,只好自己简单的学习了一下 wait()/notify()机制,写了一个很小的线程池. 代码如下(一共2个类): /* *一个简单的线程池 ThreadPool .java */ public class ThreadPool { //以下是配置信息,可以更改 static int MAX_THREAD = 1000; //未使用 static int MIN_THREAD = 14; static int id = 1; //线程 ID 号,主要用于监视线程的工作情况 static private ThreadPool pool = new ThreadPool(); static public ThreadPool getThreadPool() { return pool; } Stack<WorkThread> stack = new Stack<WorkThread>(MIN_THREAD); private ThreadPool() { } synchronized public boolean putWorkThread(WorkThread wt) { if(stack.size()<MIN_THREAD){ stack.push(wt); return true; } else { return false; } } synchronized public WorkThread getWorkThread() { WorkThread wt = null; if(stack.isEmpty()) { wt = new WorkThread(this); new Thread(wt,"线程ID:"+id).start(); id++; } else { wt = stack.pop(); } return wt; } } -------------------------------------------------------------------------- /* *工作线程类 WorkThread.java */ public class WorkThread implements Runnable { Object lock = new Object(); Runnable runner = null; ThreadPool pool = null; public WorkThread(ThreadPool pool) { this.pool = pool; } public void start(Runnable r) { runner = r; synchronized(lock) { lock.notify(); } } public void run() { while(true) { if(runner != null) { runner.run(); runner = null; //及时回收资源 } if(pool.putWorkThread(this)) { System.out.println (Thread.currentThread().getName()+" 被回收!"); synchronized(lock) { try { lock.wait(); } catch (InterruptedException ie) { System.out.println ("停止线程时出现异常"); } } } else { System.out.println (Thread.currentThread().getName()+" 被丢弃!"); break; } } } }
使用方法: Runnable r = ......; new Thread(r).start(); 这是你以前的代码,使用线程池只需要将后一句变成 ThreadPool.getThreadPool().getWorkThread().start(r); 就可以了,其他的代码不用任何更改.
这个线程池还有两个功能没有实现: 1.最大线程数的控制 2.空闲线程等待一定时间后自动注销 但这个线程池也有一个好处--可以随时改变最小线程的数量.
由于学 Java 不太懂,其中可能有不太完善的地方,还请各位高手指点一下,谢谢!!
|