目录
Thread类中的stop方法【不推荐】
查看源码
通过源码可以看到stop()方法会强制线程停止运行
java
package java.lang;
// ...
public
class Thread implements Runnable {
// ...
// Forces the thread to stop executing.
@Deprecated
public final void stop() {
// ...
stop0(new ThreadDeath());
}
// ...
}
测试
java
package concurrency;
public class ThreadStopTest {
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
}
});
t.start();
// 1秒后查看t线程是否为活跃状态
sleepTime(1_000);
System.out.println("t线程是否活跃:" + t.isAlive());
// 3秒后强制t线程停止运行
long beginTime = System.currentTimeMillis();
sleepTime(3_000);
t.stop();
while (true) {
if (!t.isAlive()) {
long endTime = System.currentTimeMillis();
System.out.println((endTime - beginTime) + "ms");
break;
}
}
}
public static void sleepTime(long time) {
if (time <= 0) return;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
不推荐使用的原因
- 方法已废弃,不建议使用
- 方法本身不安全
使用标志位的判断来结束线程的执行【不推荐】
实现案例
java
package concurrency;
public class FlagTest {
private volatile static boolean flag = true;
public static void main(String[] args) {
new Thread(() -> {
while (flag) {
}
}).start();
// 3秒后,通过改变flag标识来停止线程t
try {
Thread.sleep(3_000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
flag = false;
}
}
不推荐使用的原因
- 在很多场景下并没有机会去判断标志位(如任务长时间阻塞等待)
通过对线程对象的封装来停止线程的执行【推荐】
实现思路
- 封装一个类,提供两个方法,分别为执行任务的方法和超时停止任务执行的方法
- 通过daemon和interrupt来实现
具体实现
java
package concurrency;
public class ThreadService {
private Thread executeThread;
private volatile boolean isFinish = false;
/**
* 执行任务
*/
public void execute(Runnable task) {
if (task == null) return;
executeThread = new Thread(() -> {
Thread t = new Thread(task);
// 设置为守护线程
t.setDaemon(true);
t.start();
try {
// task执行完
t.join();
isFinish = true;
} catch (InterruptedException e) {
System.out.println("任务执行超时...");
}
});
executeThread.start();
}
/**
* 超时停止任务的执行
*/
public void shutdown(long timeout) {
if (timeout <= 0) return;
long currentTime = System.currentTimeMillis();
while (!isFinish) {
// 超时,打断执行任务的线程,使其结束
if (System.currentTimeMillis() - currentTime > timeout) {
executeThread.interrupt();
break;
}
// 减少空转次数
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}
}
}
测试
案例一:任务未超时
java
package concurrency;
public class ThreadServiceTest {
public static void main(String[] args) {
// 任务:从数据库中查询数据
Runnable queryDataFromDB = () -> {
try {
// 这里该任务执行耗时10s
Thread.sleep(10_000);
System.out.println("queryDataFromDB task execute success!");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
};
// 执行任务
ThreadService threadService = new ThreadService();
long beginTime = System.currentTimeMillis();
threadService.execute(queryDataFromDB);
// 最大忍耐限度为20s,任务没有超过20s就按照实际耗时执行成功
threadService.shutdown(20_000);
long endTime = System.currentTimeMillis();
System.out.println("总耗时:" + (endTime - beginTime) + "ms");
}
}

案例二:任务执行超时
java
package concurrency;
public class ThreadServiceTest {
public static void main(String[] args) {
// 任务:从数据库中查询数据
Runnable queryDataFromDB = () -> {
try {
// 这里该任务执行耗时30s
Thread.sleep(30_000);
System.out.println("queryDataFromDB task execute success!");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
};
// 执行任务
ThreadService threadService = new ThreadService();
long beginTime = System.currentTimeMillis();
threadService.execute(queryDataFromDB);
// 最大忍耐限度为20s,如果任务执行超过20s则认为任务失败,停止任务
threadService.shutdown(20_000);
long endTime = System.currentTimeMillis();
System.out.println("总耗时:" + (endTime - beginTime) + "ms");
}
}
