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);
}
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


