在子线程中出现没有明确退出条件,或者需要在发出中断信号后及时结束的逻辑中,一定要手动检测线程结束标志位
正确案例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Demo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new SubThread());
executorService.submit(new SubThread());
executorService.shutdown();
try {
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("线程池关闭超时");
// 触发强制关闭,将 标志位 置为 interrupted
executorService.shutdownNow();
if (!executorService.awaitTermination(3, TimeUnit.SECONDS)) {
System.out.println("线程池强制关闭失败");
} else {
System.out.println("线程池强制关闭成功");
}
} else {
System.out.println("线程池关闭成功");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
class SubThread implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
错误案例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Demo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new SubThread());
executorService.submit(new SubThread());
executorService.shutdown();
try {
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("线程池关闭超时");
executorService.shutdownNow();
if (!executorService.awaitTermination(3, TimeUnit.SECONDS)) {
System.out.println("线程池强制关闭失败");
} else {
System.out.println("线程池强制关闭成功");
}
} else {
System.out.println("线程池关闭成功");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
class SubThread implements Runnable {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}