徹底停止運行線程池ThreadPoolExecutor

最近系統開發時遇到這樣一個需求:

該功能執行時間很久,如果運行過程出現錯誤,也無法將其停止,必須眼睜睜的看着它浪費很久時間,除非停止服務器。

於是,我就想着如何給該功能加上一個“停止”的功能呢?

經過不斷的思考和測試,發現思路如此簡單,直接上代碼!

package com.iamzken.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest {
	//線程池
	private static ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 5,
			TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
			new ThreadPoolExecutor.CallerRunsPolicy());
	//定義一個線程,相當於父線程
	private static Thread t;
	//保存線程池中當前所有正在執行任務的活動線程,相當於子線程
	private static List<Thread> activeThreads = new ArrayList<Thread>(5);
	//根據參數b的值,決定是啓動線程還是停止線程
	public static void test(boolean b) {

		if (b) {
			System.out.println("start========================================");
			//停止父線程,這裏使用了Thread類的暴力停止方法stop
			t.stop();
			//遍歷並停止所有子線程,這裏使用了Thread類的暴力停止方法stop
			//這裏一定要把子線程也停止掉,原來以爲停止了父線程,子線程就會自動停止,事實證明這是錯誤的,必須在停止父線程的同時停止掉子線程才能徹底停止掉整個線程
			for (int i = 0; i < activeThreads.size(); i++) {
				Thread t = activeThreads.get(i);
				System.out.println(t.getName());
				t.stop();
			}
			
			System.out.println("stop==========================================");
		} else {
			//創建父線程
			t = new Thread() {
				@Override
				public void run() {
					//創建線程池要執行的兩個任務r1和r2。這兩個任務都是死循環
					Runnable r1 = new Thread() {
						@Override
						public void run() {
							Thread currentThread = Thread.currentThread();
							activeThreads.add(currentThread);
							int i = 1;
							while (true) {
								System.out.println(currentThread.getName()+"------------>"+(i++));
								try {
									Thread.sleep(1000);
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
						}
					};
					Runnable r2 = new Thread() {
						@Override
						public void run() {
							Thread currentThread = Thread.currentThread();
							activeThreads.add(currentThread);
							int i = 1;
							while (true) {
								System.out.println(currentThread.getName()+"------------>"+(i++));
								try {
									Thread.sleep(1000);
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
						}
					};
					//在線程池中執行兩個任務r1和r2,實際上相當於在t中開啓了兩個子線程,而兩個子線程由線程池維護而已
					pool.execute(r1);
					pool.execute(r2);
				};
			};
			//啓動父線程
			t.start();
		}
	}
	//測試方法
	public static void main(String[] args) {
		//傳入false代表要啓動線程執行任務
		test(false);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//執行任務5秒之後,傳入false代表要停止線程
		test(true);
	}

}


原來以爲停止了父線程,子線程就會自動停止,事實證明這是錯誤的,必須在停止父線程的同時停止掉子線程才能徹底停止掉整個線程!
另:停止線程我使用了Thread類中的暴力停止方法stop,因爲其他方法都不徹底,如有其他更好的方法,朋友們可以及時與我交流!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章