首页 > 代码库 > 漫谈并发编程(四):终结任务
漫谈并发编程(四):终结任务
使用状态变量来终结任务
有时我们可以使用一个状态变量(如布尔值)来终结任务的执行,这种方式非常平和,且提供给你机会在任务终止前做一些操作。如:
public class StateStopTask implements Runnable{ private static volatile boolean isCancled = false; public void run() { while(true) { if(isCancled == true) { System.out.println("StateStopTask is stop"); return; } } } public static void main(String []args) { new Thread(new StateStopThread()).start(); Thread.sleep(3000); isCancled = true; } }
或者直接使用Thread.interrupt()来设置线程的中断标识,并且在程序中检测该标识,可以避免状态变量的定义。
public class StateStopTask implements Runnable{ public void run() { while(!Thread.currentThread().isInterrupted()) { System.out.println("StateStopTask is running"); } System.out.println("StateStopTask is stopping"); } public static void main(String []args) { Thread t = new Thread(new StateStopThread()).start(); Thread.sleep(3000); t.interrupt(); } }
在阻塞时终结
前面使用状态变量只能在线程运行到该检测时才能终止,有时我们需要线程无论在何时何地都能够被终止,尤其是在阻塞的时候。一个任务进入阻塞状态,可能有如下原因:
- 通过调用sleep(milliseconds)使任务进入休眠状态,在这种情况下,任务在指定的时间内不会运行。
- 你可以通过wait()使线程挂起。直到线程得到了notify()或notifyAll()消息(或者在JavaSE5的java.util.concurrent类库中等价的signal()或signalAll()消息),线程才会进入就绪状态。
- 任务在等待某个输入输出完成。
- 任务试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。
中断
程序在由于sleep或者wait()导致的阻塞情况下,如果被调用interrupt()方法将抛出interruptedExcetion异常,并且中断状态将清除。程序在由于IO和锁的阻塞时,调用interrupt()方法不会抛出interruptedException,但会设置中断状态。使用interrupted()可以检测中断状态并且如果正处于中断则清除中断状态,所以在程序中一般使用下面的方式检测中断,并做善后处理:
public class InterruptedTask implements Runnable{ public void run() { while(!Thread.currentThread().interrupted()) { try { System.out.println("InterruptedTask running"); Thread.sleep(100); } catch (InterruptedException e) { System.out.println("interrupted by InterruptedException ") } } System.out.println("InterruptedTask Interrupted") } }
现代java代码不推荐直接操作Thread对象,转而尽量通过Executor来执行所有操作。如果你在Executor上调用shutdownNow(),那么它将发送一个interrupt()调用给它启动的所有线程。这样做是常见的,因为一个Executor通常执行同一类任务,所以经常会希望关闭Executor的所有任务。然后,你有时会希望只中断单一的任务。如果使用Executor,那么通过调用submit()而不是executor()来启动任务,就可以持有该任务的上下文,submit()将返回一个泛型Future<?>,其中有一个未修饰的参数,因为你不能调用get(),使用这个Futrue对象可以调用cancle(),如果传递true给cancle(),那么在这个线程上就会调用interrupt()方法。
一般由于锁而导致的阻塞无法中断,但原子锁(ReentrantLock)支持可中断的阻塞操作lockInterruptibly()。
漫谈并发编程(四):终结任务
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。