Asynchronous interrupt
中斷请求信号来自CM3内核的外面,来自各种片上外设和外扩的外设,对CM3来说是“异步”的;
e.g. usb otg device
Synchronous interrupt
在执行指令或访问存储器时产生,因此对CM3来说是“同步”的。
e.g. assembly language
int 31
interrupt
首先梳理Thread关于interrupt的定义
/** * Interrupts this thread. * * <p> Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * * <p> If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * * <p> If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread's interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * * <p> If this thread is blocked in a {@link java.nio.channels.Selector} * then the thread's interrupt status will be set and it will return * immediately from the selection operation, possibly with a non-zero * value, just as if the selector's {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * * <p> If none of the previous conditions hold then this thread's interrupt * status will be set. </p> * * <p> Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException * if the current thread cannot modify this thread * * @revised 6.0 * @spec JSR-51 */ public void interrupt()
这里讲述了Thread实例对象调用方法interrupt,有这几种情况
1.在线程里面有wait,sleep,join方法,会弹出InterruptedException,状态会被清除
2.io里面,会弹出异常,状态会被设置,…
3.如果线程阻塞在nio中的Selector中,状态会被设置,…
4.如果不是上面,这些情况,状态会被设置
可以看出interrupt是关于状态的设置
我们来验证一下
第一种,没有任何情况的
public static void main(String[] args) { Thread t1 = new Thread(()->{ while(true){ if (interrupted()) { break; } System.out.println("i" + new Date()); } }); t1.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t1.interrupt(); }
线程会在(1000+)ms后结束,整个程序也会结束
第二种,有sleep的情况下
public static void main(String[] args) { Thread t1 = new Thread(()->{ while(true){ if (interrupted()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("i" + new Date()); } }); t1.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t1.interrupt(); }
方法并不会退出,只是打出了一个InterruptException
作者:大闲人柴毛毛
链接:https://www.zhihu.com/question/41048032/answer/252905837
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如何处理中断?
上文都在介绍如何获取中断状态,那么当我们捕获到中断状态后,究竟如何处理呢?
- Java类库中提供的一些可能会发生阻塞的方法都会抛InterruptedException异常,如:BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep。
- 当你在某一条线程中调用这些方法时,这个方法可能会被阻塞很长时间,你可以在别的线程中调用当前线程对象的interrupt方法触发这些函数抛出InterruptedException异常。
- 当一个函数抛出InterruptedException异常时,表示这个方法阻塞的时间太久了,别人不想等它执行结束了。
- 当你的捕获到一个InterruptedException异常后,亦可以处理它,或者向上抛出。
- 抛出时要注意???:当你捕获到InterruptedException异常后,当前线程的中断状态已经被修改为false(表示线程未被中断);此时你若能够处理中断,则不用理会该值;但如果你继续向上抛InterruptedException异常,你需要再次调用interrupt方法,将当前线程的中断状态设为true。
- 注意:绝对不能“吞掉中断”!即捕获了InterruptedException而不作任何处理。这样违背了中断机制的规则,别人想让你线程中断,然而你自己不处理,也不将中断请求告诉调用者,调用者一直以为没有中断请求。
更新相关interrupt方法的意义
public void interrupt()
Thread里面的打断函数,可以使用新建一个Thread对象,执行
thread.interrupt();
修改调用线程的interrupt 的status
public static boolean interrupted()
该方法可以判断是否被打断,但是这个interrupt的status会被清除,
/** * Tests whether the current thread has been interrupted. The * <i>interrupted status</i> of the thread is cleared by this method. In * other words, if this method were to be called twice in succession, the * second call would return false (unless the current thread were * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if the current thread has been interrupted; * <code>false</code> otherwise. * @see #isInterrupted() * @revised 6.0 */
public boolean isInterrupted()
该方法可以判断是否被打断
在JDK之前的版本中可以通过stop、suspend来终止、中断线程的指向,不过目前这些方法已经不建议使用了,那如果希望在执行到某一条件时中断线程的执行,应该怎么做呢?目前推荐的方式是通过interrupt来实现。
一 源码分析
1 interrupt()
Thread#interrupt()的作用其实也不是中断线程,而是通知线程应该中断了,具体来说,当对一个线程调用interrupt() 时:
- 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常,仅此而已。
- 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。
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(this);
return;
}
}
interrupt0(); // Just to set the interrupt flag
}
2 interrupted()
检查当前中断标识(即查看当前中断信号是true还是false),并清除中断信号。一般处理过中断以后使用此方法。
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/**
* 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);
3 isInterrupted()
检查当前中断标识(即查看当前中断信号是true还是false)
public boolean isInterrupted() {
return isInterrupted(false);
}
二 示例
以下示例展示了通过isInterrupted()、interrupt()如何终止执行中的线程,如下所示代码中中创建了两个线程(thread1、thread2),thread1每隔500ms数数一次,thread2休眠一段时间以后中断thread1,thread1将会终止。
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
int i = 0;
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(500);
System.out.println("couting... i=" + i);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("thread1 interrupted");
}
});
Thread thread2 = new Thread(() -> {
Random random = new Random();
try {
long time = random.nextInt(3000) + 1000;
Thread.sleep(time);
System.out.println("interrupt thread1");
thread1.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
Asynchronous interrupt
中斷请求信号来自CM3内核的外面,来自各种片上外设和外扩的外设,对CM3来说是“异步”的;
e.g. usb otg deviceSynchronous interrupt
在执行指令或访问存储器时产生,因此对CM3来说是“同步”的。
e.g. assembly language
int 31Reference
转载于:https://www.cnblogs.com/youchihwang/p/7553809.html