面试题答案
一键面试线程抛出异常后生命周期的影响
在Java并发场景下,当线程抛出未捕获的异常时,该线程会终止。线程一旦终止,就进入了 TERMINATED
状态,它将不再执行后续代码,也无法再次启动。
健壮异常处理机制设计
- 使用
try - catch
块 在每个线程的执行代码中,使用try - catch
块捕获异常,避免异常直接导致线程终止。例如:
class MyRunnable implements Runnable {
@Override
public void run() {
try {
// 可能抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("捕获到异常: " + e.getMessage());
}
}
}
- 自定义
UncaughtExceptionHandler
通过设置Thread.UncaughtExceptionHandler
,可以在异常未被捕获时执行自定义的处理逻辑。例如:
class CustomUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("线程 " + t.getName() + " 抛出未捕获异常: " + e.getMessage());
// 可以在这里进行资源释放等操作
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
int result = 10 / 0;
});
thread.setUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
thread.start();
}
}
- 确保资源正确释放
使用
try - finally
块或try - with - resources
(针对实现了AutoCloseable
接口的资源)确保在异常发生时资源被正确释放。例如:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ResourceReleaseExample {
public static void main(String[] args) {
try (InputStream inputStream = new FileInputStream("nonexistentfile.txt")) {
// 读取文件的代码
} catch (IOException e) {
System.out.println("读取文件时发生异常: " + e.getMessage());
}
}
}
- 使用线程池 线程池可以管理线程的生命周期,当线程抛出异常时,线程池可以根据配置决定是否重新创建线程。例如:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.submit(() -> {
int result = 10 / 0;
});
executorService.shutdown();
}
}
通过以上方法,可以在Java复杂并发场景下设计健壮的异常处理机制,确保线程在异常情况下能正确释放资源并维持系统稳定性。