在java编程中我们不可避免的要使用到并发编程.假设我们现在有一个这样的需求,一个线程需要完成一个任务,但是任务执行的过程中,需要停止. 在早期的JDK版本中提供了stop suspend等方法.但是现在已经废弃掉了,因为他可能会引起某些安全问题.故我们可以认为java没有提供线程终止的机制. 所以一般情况下线程的终止是等到起任务执行完毕,然后自然而然的停止掉. 下面我们探讨两种停止的方法.
一,标志位
假设一个线程在执行过程中存在一个循环,我们预先设置一个标志位,这个标志位代表着线程是否结束,那么每次循环都去检查标志位是否发生改变,如果改变就结束当前线程,如果没有改变,就继续执行.
public void run() { //每次循环都检测标志位是否发生改变 while(!isExit){ counter++; System.out.println(Thread.currentThread().getName()+" "+counter ); } System.out.println("退出循环,线程结束"); }
二,,InterruptedException方法.
由上面我们可以看到,通过标志位的方法我们可以很自然和温柔随和的把一个线程终止掉.java中没有一种安全的抢占式方法来停止线程,因为也就没有安全的抢占式方法来停止线程.但是他有一种协作式的机制,是请求取消的任务和代码都遵循一种协商好的协议.,设置”已经请求取消”标志,而任务将定时的查看该标志. 但是我们通过上面的示例发现,使用上面的方法线程一直在运行,处于active(“活”)的状态,如果调用sleep或者wait()方法,线程将会处于睡眠或者阻塞状态那么这种方法将会不起作用——-任务可能永远不会检查取消标志,因此永远无法结束 public class InterruptedThreadDemo { public static void main(String[] args) { // 子线程开启 ThreadTerminal tt = new ThreadTerminal(); tt.start(); try { // 主线程休息3s,然后打断子线程 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 打断子线程 tt.interrupt(); }}class ThreadTerminal extends Thread { private int counter = 0; public void run() { synchronized (this) { while (true) { System.out.println("time = " + System.currentTimeMillis()); counter++; try { if (counter == 5) { // 使线程处于阻塞状态 wait(); } } catch (InterruptedException e) { // 捕获InterruptedException,然后退出程序 System.out.println("捕获到InterruptedException , 线程结束"); return; } } } }} 通过上面方法当线程阻塞状态的时候也可以被终止掉. 例如.访问网络服务器的时候, 网络请求在异步队列中, 要取消阻塞的任务
|