Interrupt与sleep
2019-07-22 本文已影响0人
可爱猪猪
作者:
可爱猪猪
-帅锅一枚
作者的网名很阔爱,如果喜欢本文章一定要点 喜欢 或者 打赏,拜托~
作者一直在进步,需要你们的支持和鼓励,谢谢!
人生理想:在程序猿界混出点名堂!
好了,先看看面这个例子,如何停止一个线程
public class LazyThread extends Thread{
// 是否被打扰
public static volatile boolean interrupted = false;
public void run() {
// 没有被打扰就继续吃
while(!interrupted) {
System.out.println("eat...");
}
// 打扰后唤醒
System.out.println("wake up...");
}
public static void main(String[] args) {
Thread lt = new LazyThread();
lt.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wake up");
LazyThread.interrupted = true;
}
}
我们采用了一个标志,来中断这个线程,可是这种方式有个问题,如果LazyThread存在sleep 或者Thread.join根本中断不了,好了,废话不多少,看下面这个例子
public class LazyThread extends Thread{
// 是否被打扰
public void run() {
// 没有被打扰就继续吃
while(!Thread.currentThread().isInterrupted()) {
System.out.println("eat...");
// 这个线程真的很懒,不断的吃和睡
try {
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 打扰后唤醒
System.out.println("wake up...");
}
public static void main(String[] args) {
Thread lt = new LazyThread();
lt.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wake up");
lt.interrupt();
}
}
看一下这个,去掉LazyThread的sleep 30秒的代码,这个代码没有什么问题,但是呢,我们这个本来是要终止sleep阻塞的,可是虽然中断了sleep,然而线程的interrupted状态依然是【非中断】,看如下运行结果:
Result1.png始终阻止不了这个lazy线程的吃操作....
于是我们还是看下JDK的代码:
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds, subject to
* the precision and accuracy of system timers and schedulers. The thread
* does not lose ownership of any monitors.
*
* @param millis
* the length of time to sleep in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static native void sleep(long millis) throws InterruptedException;
看到native方法不要着急,我们看下注释:如果任意线程已经中断了当前线程,这个interrupt状态会被清除,会抛出一个异常。
瞬间恍然大悟。
状态被清除了
好了,那该怎么办呢?
《JAVA并发编程实战》一书中其实给出了答案,对于Interrupt异常,有两种处理方式:
1.捕捉异常后,重新调用Thread.currentThread.interrupt();来修改异常状态 ,以便我们的线程的interrupt状态能被捕获,而退出循环
2.抛出异常
后语:
interrupt()方法只是打了一个标记告诉线程,线程自行处理
sleep被interrupt后,是会清除interrupt状态的。