isEndTask()用while(true){..}来判别全部线程已执行结束,不然程序就不准往下执行.while(true){..}在多线程中是很浪费CPU的,从而使得线程池中各个线程获得不多的CPU机会去执行本身各自的任务。所以影响了线程池的优点的发挥。
那如何改进代码呢?
个人建议是:
1)从ThreadPoolExecutor继承,定制它的回调方法:
protected void afterExecute(Runnable r, Throwable t),在该方法的代码中,判getActiveCount() 是否是 0,如果0,则置boolean 型变量hasFinished=true;并发出notifyAll()通知,通知synBackup()方法所在的线程,hasFinished已为true,它能够开始运行了[主要缘由是:synBackup()方法调用了下边的waitForEndTask() 方法,而该方法是用wait()等待线程池全部线程运行结束的。]。
2)isEndTask()方法的代码不能是while(true);改成:若没有完成,就wait(),放弃CPU,让CPU宝贵的资源留给线程池中的线程。所以方法名改成waitForEndTask()。代码以下:
public void waitForEndTask() {
synchronized(变量hasFinished所在的对象){
while (hasFinished==false) {
try{变量hasFinished所在的对象.wait();}
catch(InterruptedException e){}
}
}
3)这样设计的目的是:当线程池中线程没有所有运行结束时,synBackup()方法[内部调用了waitForEndTask() ]全部的线程是处于wait()下,不占用宝贵的CPU资源,让CPU资源所有留给了线程池中线程。当线程池中全部的线程全运行结束,才会经过notifyAll()来唤醒synBackup()方法全部的线程继续向下运行。java
public class MyThreadPoolExecutor extends ThreadPoolExecutor { private boolean hasFinish = false; public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new CustomThreadFactory(), new CustomRejectedExecutionHandler()); // TODO Auto-generated constructor stub } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); synchronized (this) { if(this.getActiveCount() == 1){ this.hasFinish = true; this.notify(); } } } public void isEndTask(){ synchronized (this) { while(this.hasFinish == false){ try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } class CustomThreadFactory implements ThreadFactory{ @Override public Thread newThread(Runnable r) { // TODO Auto-generated method stub Thread t = new Thread(r); System.out.println("------------------------------CustomThreadFactory.............newThread....."); return t; } } class CustomRejectedExecutionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // TODO Auto-generated method stub try { System.out.println("------------------------------CustomRejectedExecutionHandler.............rejectedExecution....."); executor.getQueue().put(r); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }