1.2中断线程
线程将在它的run方法返回时终止,还可以用interrupt方法来请求终止一个线程。
当interrupt方法在一个线程上被调用时,该线程的中断状态(interrupted status)将会被置位。这是一个布尔型的标志 ,存在于每个线程中。每个线程都不时检查该标志,以判断线程是否应该被中断。
为了查看中断状态,需要首先调用静态的Thread.currentThread方法来取得当前线程,然后调用他的isInterrupted方法:
while(!Thread.currentThread().isInterrupted()){
//do more work
}
尽管如此,若一个线程被阻塞了,它就无法检查中断状态了,就会产生interruptedException。当被阻塞的线程上调用interrupt方法时,the blocking call(例如sleep 或wait)
就会被interruptedException异常所终止。
一个被中断的线程不应该终止。中断一个线程只是为了引起线程的注意,被中断线程可决定如何应对中断。某些线程很重要,不应理会中断,而是在处理完抛出异常后继续执行。但是 普遍的情况是,一个线程把中断看作一个终止的请求。这种线程的run方法一般是如下形式:
public void run(){
try{
//...
while(!Thread.currentThread().isInterrupted()//&& more work to do){
//do more work
}
}catch(InterruptedExcetion e){
//thread was interrputed during sleep or wait
}finally{
cleanup,if required
}
//exiting the run method terminates the thread
}
如果你在每次工作迭代之后都调用sleep方法,那么这个is Interrupted检查就不是必须的。如果你在中断状态被置位时调用sleep方法,那么sleep方法将抛出InterruptedException异常。因此,若 你循环调用sleep,就要花点心思检查中断状态并捕获该异常,这样run方法形式如下:
public void run()
{
try
{
. . .
while (more work to do)
{
do more work
Thread.sleep(delay);
}
}
catch(InterruptedException e)
{
// tHRead was interrupted during sleep or wait
}
finally
{
cleanup, if required
}
// exiting the run method terminates the thread
}
当sleep方法抛出一个InterruptedException异常时,它同时会清除中断状态,我在想那么前一种呢sleep期间访问中断状态,这种情况是否会清除中断状态?
注意: Interrupted
是一个静态方法,检查当前线程是否已被中断,而且调用interrupted方法会清除该进程的中断状态。而isInterrupted方法是一个实例方法,可用它检查是否有线程被中断了,调用它不会改变中断状态的值。
You'll find lots of published code in which the InterruptedException is squelched at a low level, like this:
void mySubTask()
{
. . .
try { sleep(delay); }
catch (InterruptedException e) {} // DON'T IGNORE!
. . .
}
Don't do that! If you can't think of anything good to do in the catch clause, you still have two reasonable choices:
In the catch clause, call THRead.currentThread().interrupt() to set the interrupted status. Then the caller can test it.
void mySubTask()
{
. . .
try { sleep(delay); }
catch (InterruptedException e) { Thread().currentThread().interrupt(); }
. . .
}
Or, even better, tag your method with throws InterruptedException and drop the try block. Then the caller (or, ultimately, the run method) can catch it.
void mySubTask() throws InterruptedException
{
. . .
sleep(delay);
. . .
}
要点归纳:
void interrupt()
发送一个中断请求给一个线程。该线程的中断状态将被设为True。若该线程当前被sleep调用阻塞将抛出InterruptedException异常。
static boolean interrupted()
检查当前线程是否已被中断了,静态方法,调用它的副作用是它会将当前线程的中断状态设为false。
boolean isInterrupted()
检查一个线程是否已被终止了,该调用不改变线程的中断状态。
static Thread currentThread()
返回代表当前执行的线程的Thread对象。