Java代码如何终止线程呢?
下文笔者讲述java代码终止线程的方法分享,如下所示
终止线程的实现思路
方式1: 使用退出标志 使线程正常退出 当run()方法完成后线程中止 方式2: 使用stop()方法强行终止线程(此方法已被弃用) 方式3: 使用interrupt方法中断线程
使用标志位终止线程
当run()方法运行完毕后 该线程就终止 但是在某些特殊情况下 run()方法会被一直执行 如: 在服务端程序中可能会使用 while(true) { ... } 这样的循环结构来不断的接收来自客户端的请求 此时就可以用修改标志位的方式来结束 run() 方法例
public class ServerThread extends Thread { //volatile修饰符用来保证其它线程读取的总是该变量的最新的值 public volatile boolean exit = false; @Override public void run() { ServerSocket serverSocket = new ServerSocket(8080); while(!exit){ serverSocket.accept(); //阻塞等待客户端消息 ... } } public static void main(String[] args) { ServerThread t = new ServerThread(); t.start(); ... t.exit = true; //修改标志位,退出线程 } }
使用stop()终止线程
在JDK的API中 可得知java.lang.Thread类型提供一系列的方法 如:start()、stop()、resume()、suspend()、destory()等方法来管理线程 但是除start()之外 其它几个方法都被声名为已过时(deprecated)
弃用stop方法的缘由
当我们调用stop()方法时 会立刻停止run()方法中剩余的全部工作 包括在catch或 finally语句中, 并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获) 因此可能会导致一些清理性的工作的得不到完成 如文件,数据库等的关闭。 调用stop()方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题 如: 存在一个对象obj持有 ID 和 NAME 两个字段 当写入线程在写对象的过程中 只完成了对ID的赋值 但没来得及为NAME赋值 此时被stop()导致锁被释放 那么当读取线程得到锁之后再去读取对象obj的ID和Name时 就会出现数据不一致的问题
使用interrupt()中断线程
优雅终止线程,笔者建议使用interrupt()方法 interrupt()方法 并不像在for循环语句中使用break语句那样立即停止循环 调用interrupt()方法只在当前线程中打一个停止的标记,并不是真的停止线程。 调用 interrupt()方法:线程中断并不会立即终止线程 而是通知目标线程
interrupt()示例
public class InterruptThread1 extends Thread{ public static void main(String[] args) { try { InterruptThread1 t = new InterruptThread1(); t.start(); Thread.sleep(200); t.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { super.run(); for(int i = 0; i <= 200000; i++) { System.out.println("i=" + i); } } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。