线程响应中断请求及资源释放
- 检查中断状态:在Java多线程环境下,当调用
interrupt()
方法中断线程时,线程内部应定期检查中断状态。通常在执行一些关键操作(如I/O操作、长时间计算等)的循环体中,使用Thread.currentThread().isInterrupted()
来检查当前线程是否被中断。例如:
while (!Thread.currentThread().isInterrupted()) {
// 线程执行的业务逻辑
try {
// 模拟耗时操作
Thread.sleep(100);
} catch (InterruptedException e) {
// 处理中断异常,通常是重置中断状态
Thread.currentThread().interrupt();
break;
}
}
- 释放资源:
- 文件资源:如果线程在执行过程中打开了文件,应在检测到中断请求后关闭文件。例如使用
try - finally
块:
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
while (!Thread.currentThread().isInterrupted()) {
// 读取文件内容
int data = fis.read();
if (data == -1) break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- **网络资源**:如果线程涉及网络连接,如`Socket`,同样需要在中断时关闭连接。例如:
Socket socket = null;
try {
socket = new Socket("localhost", 8080);
while (!Thread.currentThread().isInterrupted()) {
// 网络读写操作
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 确保线程安全停止:除了检查中断状态和释放资源,还需要确保对共享资源的访问是线程安全的。例如,使用
synchronized
关键字或Lock
接口来保护共享资源。
isInterrupted()
和Thread.interrupted()
方法的区别及应用场景
- 区别:
isInterrupted()
:这是Thread
类的实例方法,调用该方法不会改变线程的中断状态。例如:
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 线程执行逻辑
}
});
thread.start();
thread.interrupt();
boolean isInterrupted = thread.isInterrupted(); // 这里获取的中断状态不会改变中断标识
- **`Thread.interrupted()`**:这是`Thread`类的静态方法,调用该方法不仅会返回当前线程的中断状态,而且会清除当前线程的中断状态(将中断标识位设为`false`)。例如:
Thread thread = new Thread(() -> {
while (!Thread.interrupted()) {
// 线程执行逻辑
}
});
thread.start();
thread.interrupt();
boolean isInterrupted1 = Thread.interrupted(); // 获取中断状态并清除中断标识
boolean isInterrupted2 = Thread.interrupted(); // 再次调用返回false,因为标识已清除
- 应用场景:
isInterrupted()
:适用于需要多次检查线程中断状态的场景,特别是在循环中持续判断中断状态而不希望清除中断标识的情况。例如,在一个需要不断轮询任务是否被中断的线程中:
while (!Thread.currentThread().isInterrupted()) {
// 执行任务
}
- **`Thread.interrupted()`**:适用于在捕获`InterruptedException`异常后,需要处理中断逻辑并重置中断状态的场景。如前面在`Thread.sleep()`等会抛出`InterruptedException`异常的代码块中,捕获异常后调用`Thread.currentThread().interrupt()`来重置中断状态,也可以直接使用`Thread.interrupted()`来获取并清除中断状态。另外,在一些需要基于中断状态进行一次性处理的场景中也适用,因为它会清除中断状态,避免重复处理中断。