终止线程的 4 种方式

正常运行结束

程序运行结束,线程自动结束。

使用标志位

一般 run() 方法执行完,线程就会正常结束,然而,常常有些线程是伺服线程。它们需要长时间的运行,只有在外部某些条件满足的情况下,才能关闭这些线程。使用一个变量来控制循环,例如:最直接的方法就是设一个 boolean 类型的标志,并通过设置这个标志为 true 或 false 来控制 while 循环是否退出,代码示例:

public class ThreadSafe extends Thread {
	
	public volatile boolean exit = false;
	
	public void run() {
		while(!exit){
			//do something
		}
	}
}

定义了一个退出标志 exit,当 exit 为 true 时,while 循环退出,exit 的默认值为 false。在定义 exit 时,使用了一个 Java 关键字 volatile,这个关键字的目的是使 exit 同步,也就是说在同一时刻只能由一个线程来修改 exit 的值。

interrupt() 方法

使用 interrupt() 方法,通知线程应该中断了,但具体被通知的线程是中断还是继续去执行,应该由被通知的线程自己去处理。

调用 interrupt() 时有以下两种情况:

  1. 如果线程处于阻塞状态,那么线程立即退出被阻塞并抛出一个 InterruptedException 异常

  2. 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true。被设置中断标志的线程将继续正常运行,不受影响。

因此,interrupt() 并不能真正的中断线程,需要被调用的线程自己配合才行。

  1. 在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程

  2. 在调用 interrupt() 时,正确处理 InterruptedException 异常,例如在 catch 异常后就结束线程。

public class ThreadSafe extends Thread {
	public void run() {
		while (!isInterrupted()){  //非阻塞过程中通过判断中断标志来退出
			try{
				Thread.sleep(5*1000); //阻塞过程捕获中断异常来退出
			}catch(InterruptedException e){
				e.printStackTrace();
				break; //捕获到异常之后,执行 break 跳出循环,结束线程
			}
		}
	}
}

stop() 方法

程序中可以直接使用 thread.stop() 来强行终止线程,但是 stop 方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,不安全主要是:如果在调用 thread.stop() 后导致了该线程所持有的所有锁的突然释放(不可控制),那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。因此,并不推荐使用 stop() 方法来终止线程。

发布了42 篇原创文章 · 获赞 11 · 访问量 3808

猜你喜欢

转载自blog.csdn.net/weixin_44584387/article/details/104703734