本文共 2880 字,大约阅读时间需要 9 分钟。
提到中断线程,首先想到的可能是stop()方法。然而,这个方法已被官方退化为不推荐使用。以下是官方给出的原因:
停止执行:调用stop()方法会立即停止run()方法中剩余的所有工作,包括catch或finally语句中的内容,并抛出ThreadDeath异常。这种异常通常情况下不需要显式捕获,可能导致文件、数据库等资源未能完成正确关闭。
锁定问题:stop()方法立即释放线程所持有的所有锁定,导致数据同步错误,可能造成数据不一致。
因此,我们不能使用stop()方法来中断线程。
使用interrupt()方法能否中断线程?答案是否定的。
interrupt()方法只是设置线程的一个标志,便通知线程可以中断,但实际中断时机由线程自己决定。以下是通过一个简单示例来理解:
public class InterruptedTask implements Runnable { @Override public void run() { Thread currentThread = Thread.currentThread(); while (true) { if (currentThread.isInterrupted()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); // 在这里,我们需要重新设置中断标记 currentThread.interrupt(); } } }}public class InterruptedTest { public static void main(String[] args) { InterruptedTask task = new InterruptedTask(); Thread thread = new Thread(task); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt(); }}
运行结果显示,线程并未退出。这是因为:
要正确中断线程,必须在捕获异常后重新设置中断标记:
public class InterruptedTask implements Runnable { @Override public void run() { Thread currentThread = Thread.currentThread(); while (true) { if (currentThread.isInterrupted()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); // 重新设置中断标记 currentThread.interrupt(); } } }}
为了更好地控制线程的中断,可以使用自定义标志位。例如,在服务器程序中,线程可能进入一个持续接收客户端请求的循环,使用标志位来终止线程:
public class ServerThread extends Thread { public volatile boolean exit = false; // 保证多线程环境下读取最新值 @Override public void run() { ServerSocket serverSocket = new ServerSocket(8080); while (!exit) { try { Socket socket = serverSocket.accept(); // 处理客户端请求 socket.close(); } catch (IOException e) { // 处理socket异常 } } } public static void main(String[] args) { ServerThread server = new ServerThread(); server.start(); try { // 做一些运算 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { server.exit = true; // 设置标志位终止线程 } }}
在这种方式下,我们可以主动控制线程何时中断,适用于需要定制化控制的场景。
中断线程的方法有三个:
根据需求选择合适的方法是关键。标志位方法提供了更高的灵活性,适合主动控制线程终止的情况。
转载地址:http://sbsuk.baihongyu.com/