interrupt方法「Interrupts」
线程的停止和暂停
1.使用退出标志,也就是等待 Run 方法运行结束
2.使用 stop 方法强行终止线程,但是这个方法已经过期而且是不安全的方式。 thorw java.lang.TnreadDeath
3.使用 interrupt 方法中断线程(interupt方法和interupted或return结合)

4.异常法 throw new InterruptedException()
interrupt()方法
使用interrupt()方法来停止线程,但 iterrupt() 方法的使用效果并不像for+break那样,马上就停止循环。调用interrupt()方法仅仅是在当前线程中打了一个停止标记。
判断线程是否终止:
interupted() 判断当前线程是否已经中断,执行后具有将状态标志清除为false的功能
isinterupted() 仅判断对象是否是已经中断的状态
在Java多线程中可以使用 Suspend() 暂停线程,使用 Resume() 方法恢复线程
yield() 方法则是用来放弃当前CPU资源的,不过很可能马上又获得CPU时间片
java中interrupt
JDK API的说明如下:
public void interrupt()
中断线程。
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。
如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。
如果以前的条件都没有保存,则该线程的中断状态将被设置。
中断一个不处于活动状态的线程不需要任何作用。
抛出:
SecurityException - 如果当前线程无法修改该线程。
注意这句:如果当前线程没有中断它自己(这在任何情况下都是允许的)
说明调用interrupt方法不一定会真的中断线程。
关于java中的interrupt()方法疑问
在java中,开启一个多线程是很简单的,只需要new一个runnable就可以了,但是要停止一个线程,却不能简单的使用Thread.stop()方法。
首先来说说java中的中断机制,Java
中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。当调用interrupt()方法的时候,只是设
置了要中断线程的中断状态,而此时被中断的线程的可以通过isInterrupted()或者是interrupted()方法判断当前线程的中断状态是
否标志为中断。我们可以从interrupt()方法来看:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt();
return;
}
}
interrupt0();
}
从这个方法中我们可以看到,最直接的调用时interrupt0()这个方法,而这个方法仅仅是设置了线程中断状态。
我们再看看isInterrupted()方法:
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
从这个方法中,我们可以猜测到,isInterrupted()方法仅仅是检查了当前线程的中断状态,但是不会清除这个状态。
我们再来看看静态方法interrupted()
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
这个方法同样是检测当前线程的中断状态,但是这个方**产生一个副作用,就是会清除当前线程的中断状态。
Thread.interrupt() VS Thread.stop()
这两个方法最大的区别在于:interrupt()方法是设置线程的中断状态,让用户自己选择时间地点去结束线程;而stop()方**在代码的运行处直接抛出一个ThreadDeath错误,这是一个java.lang.Error的子类。所以直接使用stop()方法就有可能造成对象的不一致性。
调用Thread.sleep()方法的时候,如果当前线程处于中断那状态,那么sleep()方法不会执行,同时会清除掉该状态,并且抛出interruptedException异常。
中断的使用demo:
package com.app.basic;
public class InterruptTest {
public static void main(String[] args) {
Runnable runnable1 = new Runnable() {
@Override
public void run() {
for (int i = 0; i 10; i++) {
System.out.println(i);
if (Thread.currentThread().isInterrupted()) {
System.out.println("aa");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//sleep方法抛出这个异常之后会清除中断状态,所以需要重新设置中断状态
Thread.currentThread().interrupt();
}
}
}
};
final Thread t1 = new Thread(runnable1);
Runnable runnable2 = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
t1.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
Thread的interrupt()方法
线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程
判断某个线程是否已被发送过中断请求,请使用Thread.currentThread().isInterrupted()方法(因为它将线程中断标示位设置为true后,不会立刻清除中断标示位,即不会将中断标设置为false),而不要使用thread.interrupted()(该方法调用后会将中断标示位清除,即重新设置为false)方法来判断,下面是线程在循环中时的中断方式:
while(!Thread.currentThread().isInterrupted() more work to do){
do more work
}
如果程处于了阻塞状态(如线程调用了thread.sleep、thread.join、thread.wait、1.5中的condition.await、以及可中断的通道上的 I/O 操作方法后可进入阻塞状态),则在线程在检查中断标示时如果发现中断标示为true,则会在这些阻塞方法(sleep、join、wait、1.5中的condition.await及可中断的通道上的 I/O 操作方法)调用处抛出InterruptedException异常,并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。抛出异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求。
synchronized在获锁的过程中是不能被中断的,意思是说如果产生了死锁,则不可能被中断(请参考后面的测试例子)。与synchronized功能相似的reentrantLock.lock()方法也是一样,它也不可中断的,即如果发生死锁,那么reentrantLock.lock()方法无法终止,如果调用时被阻塞,则它一直阻塞到它获取到锁为止。但是如果调用带超时的tryLock方法reentrantLock.tryLock(long timeout, TimeUnit unit),那么如果线程在等待时被中断,将抛出一个InterruptedException异常,这是一个非常有用的特性,因为它允许程序打破死锁。你也可以调用reentrantLock.lockInterruptibly()方法,它就相当于一个超时设为无限的tryLock方法。
Java 多线程 关于 interrupt()方法
1。interrupt()的作用是中断本线程的执行。
本线程中断自己是被允许的;其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。
2。如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。
3。如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。
4。中断一个“已终止的线程”不会产生任何操作。
关于线程 interrupt
Thread有四个interrupt相关的方法interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted),他们分别的作用是什么?
sleep()、wait()、join()这些方法抛出的InterruptedException跟这几个方法又有什么关系?
我们查看interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted)这四个方法的注释,会发现都提到了一个状态interrupt status,这个状态true/false即为线程状态的一个标识位, 注意,这只是线程的一种中断机制,不一定会中断正在运行的线程,只是告诉线程选择在合适的时机中断自己。 这句话怎么理解呢?
也就是说我们的线程正常运行,外界通过一些操作改变了线程的interrupt status,线程并不会中断,只是改变了线程的interrupt status。
例1
例1 执行结果如下,可见interrupt方法只是改变了interrupt status,并没有中断线程的执行
sleep()、wait()、join()这些方法抛出的InterruptedException就跟interrupt status有关,这几个方**一直监听interrupt status,一旦监听到这个status为true,则会抛出InterruptedException,并且会把这个状态clear为false。
例2
执行结果如下:
通过例1,我们知道调用interrupt方法,会把interrupt status置为true,而这里sleep监听interrupt status为true后会抛出InterruptedException,并且又将interrupt status重新clear为false,例2验证了这点。
现在理解了interrupt status这点后,我们就可以反过来看一下interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted)这四个方法。
interrupt方法就是调用native方法将interrupt status置为true
isInterrupted()方法是一个native方法,会返回当前线程是否被interrupted,并且会根据传参ClearInterrupted来判断是否重置interrupt status
isInterrupted() 方法调用的上面的isInterrupted(boolean ClearInterrupted),并且传参false,说明会返回interrupt status,但是不会重置interrupt status
interrupted()方法也是调用的isInterrupted(boolean ClearInterrupted)方法,并且传参true,同样会返回interrupt status,并且会将状态重置为false
总结:线程的这种中断机制,是把线程的中断交给线程自己去处理,线程内部通过interrupt status去合理的中断线程,比如去清理资源等,而不是暴力的直接终止线程的运行。