判斷多線程是否執行完成

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();
		}
	}
	
}
相關文章
相關標籤/搜索