“当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时,或则和出现了在方法中没有捕获的异常时,线程将终止。”
“在早期的java版本中,有一个stop()方法,其他线程可以调用它来终止程序。但是,这个方法已经被弃用了。”
“没有可以强制线程终止的办法。”
我差点被说哭了。两个字,悲壮。
“然而,interrupt()方法可以用来请求终止线程。”
都给我学。
每个线程都具有一个boolean类型的中断标志位。当对一个线程调用interrupt方法时,这个标志位就会发生变化。所以每个线程都应该时不时地检查这个标志来判断线程是否被中断。
判断分两步:
1.调用静态Thread.currentThread()方法获得当前线程
2.调用isInterrupted()方法
如下:
while(!Thread.currentThread().isInterrupted()&& *more work to do*)
{
*do more work*
}
但是,如果线程被阻塞(调用sleep或wait),就无法检测中断状态,这会产生InterruptedException异常。
所以这时候分成了两种run()方法:
1.不被阻塞
Runnable r=()->{
try
{
...
while(!Thread.currentThread().isInterrupted()&& more work to do)
{
do more
}
}
catch(InterruptedException e)
{
//thread was interrupted during sleep or wait
}
finally
{
cleanup,if required
}
};
2.被阻塞,如:
Runnable r=()->{
try
{
...
while()
{
do more
Thread.sleep(delay);
}
}
catch(InterruptedException e)
{
//thread was interrupted during sleep
}
finally
{
cleanup,if required
}
};
注意,第二种情况并不是不处理了,因为在这种情况下很容易被程序员直接处理成以下反面例子:
void mySubTask()
{
...
try{ sleep(delay); }
catch(InterruptedException e){ }//Don't ignore!!!
}
注:catch里直接为空。
所以,下面是第二种情况的两种推荐方式:
1.在catch子句中调用Thread.currentThread().interrupt()来设置中断状态。
void mySubTask()
{
...
try{ sleep(delay); }
catch (InterruptedException e){ Thread.currentThread().interrupt(); }
...
}
2.或者,更好的方法是,用throws InterruptedException标记你的方法,不采用try语句块捕获异常。
void mySubTask() throws InterruptedException
{
...
sleep(delay);
...
}