您的位置:首页 > 其它

线程的interrupt中断和取消机制

2014-04-08 15:40 288 查看
每一个线程都有一个boolean类型的中断状态。当中断线程时,这个线程的中断状态将被设置为true,在Thread中,有以下三个方法中断线程和查询线程中断状态的方法。

public class Tread{

public void interrupt(){....}

public boolean isInterrupted(){....}

public static boolean interrupted(){....}

}

interrupt方法将中断目标线程,而isInterrupted方法能返回目标线程的中断状态,interrupted将清除当前线程的中断状态,并返回它之前的值,也是清除中断状态的唯一方法。

阻塞库方法,例如Thread.sleep和Object.wait等,都会检查线程的中断状态,并且在发现中断时提前返回。他们在响应中断时的执行操作:清除中断状态,抛出InterruptedException,

表示阻塞操作由于中断而提前结束。

中断操作不会真正的中断一个正在运行的线程,而是发出中断请求。然后由线程在一个合适的时刻中断自己。(这个时刻也被称为取消点)。通常,中断是实现取消的最合理方式。

由于每一个线程拥有各自的中断策略,因此除非你知道中断对改线程的含义,否则就不应该中断这个线程。

当调用可中断的阻塞函数时,如BlockingQueu.put等,有两种实用策略可用于处理InterruptedException:

1.传递异常,从而使你的方法也成为可中断的阻塞方法。

2.恢复中断状态,从而使调用栈中的上层代码能够对其进行处理。

传递异常相对简单,如果不想传递异常或者无法传递InterruptedException(或许通过Runnable来定义任务),那么需要另一种方式来保存中断。一种标准方法就是通过再次调用interrupt来恢复中断状态。你不能屏蔽InterruptedException,例如在catch块中捕获到异常去不做任何处理,除非在你的代码中实现了线程的中断策略。

例如不可取消的任务在退去前恢复中断

public Task getNextTask(BlockingQueue<Task> queue){

boolean interrupted = false;

try{

while(true){

try {

return queue.take();

} catch (InterruptedException e) {

// try again

interrupted=true;

}

}

}finally{

if(interrupted){

Thread.currentThread().interrupt();

}

}

}

如果过早设置中断状态,就可能引起无限循环,因为大多数可中断的阻塞方法都会在入口处检查中断状态,并且当发现被设置时会立即抛出InterruptedException异常。(检查中断,从而尽快响应中断)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: