最近系統開發時遇到這樣一個需求:
該功能執行時間很久,如果運行過程出現錯誤,也無法將其停止,必須眼睜睜的看着它浪費很久時間,除非停止服務器。
於是,我就想着如何給該功能加上一個“停止”的功能呢?
經過不斷的思考和測試,發現思路如此簡單,直接上代碼!
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,因爲其他方法都不徹底,如有其他更好的方法,朋友們可以及時與我交流!