“Java中断及中断响应”的版本间差异
跳到导航
跳到搜索
(建立内容为“category:Java”的新页面) |
无编辑摘要 |
||
第1行: | 第1行: | ||
[[category:Java]] | [[category:Java]] | ||
== 中断机制 == | |||
<pre> | |||
Java的中断为协作机制,即 A 不能直接中断 B,而是调用 “B.interrupt()” 来申请中断 B (设置中断状态);然后由 B 通过 “interrupted()”(会重置中断状态)或 “isInterrupted()”(不会重置中断状态)读取中断状态,并决定如何响应。 | |||
</pre> | |||
Java的中断: | |||
# 没有可以强制线程终止的方法。 | |||
# interrupt 方法用于'''请求终止线程'''。 | |||
=== 中断相关源码 === | |||
<syntaxhighlight lang="java"> | |||
private volatile Interruptible blocker; // | |||
private final Object blockerLock = new Object(); // 用于synchronized锁定,实现同步安全 | |||
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code | |||
*/ | |||
void blockedOn(Interruptible b) { | |||
synchronized (blockerLock) { | |||
blocker = b; | |||
} | |||
} | |||
... | |||
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); // 调用Interruptible对象b 的同步方法 | |||
return; | |||
} | |||
} | |||
interrupt0(); | |||
} | |||
public static boolean interrupted() { | |||
return currentThread().isInterrupted(true); | |||
} | |||
public boolean isInterrupted() { | |||
return isInterrupted(false); | |||
} | |||
private native boolean isInterrupted(boolean ClearInterrupted); | |||
... | |||
private native void interrupt0(); | |||
</syntaxhighlight> | |||
其中: | |||
# “interrupt()” 方法只是调用了“blocker.interrupt()”和“interrupt0()”,并不对线程运行产生影响; | |||
# “blocker”域用于 nio 的中断?【???待查证】 | |||
# “interrupt0()” 是一个 native方法,仅用于设置中断标识(其他的); | |||
# “interrupted()”(静态方法)和“isInterrupted()”(实例方法)最终都是调用本地方法“isInterrupted”; | |||
# “isInterrupted”是一个 native方法,用于判断中断标识,并根据参数决定是否重置中断状态; | |||
* 中断标识的使用,都是在native方法中。 | |||
== 中断响应 == | |||
当线程处在不同的状态下(Running,Blocked,Waiting),响应中断信号的方式不一样: | |||
# 当线程处于非阻塞状态时,可以在自己需要处理中断逻辑的地方,判断中断标示位是否为true,就可以响应处理中断; | |||
# 线程处于阻塞状态时,JVM会让B线程马上抛出异常或被唤醒,从而让B线程可以选择是否响应中断; | |||
=== 响应中断的方法 === | |||
# 响应中断的方法: 线程进入'''等待或是超时等待'''的状态后,调用interrupt方法都是会响应中断的; | |||
#: 所以响应中断的方法:Object.wait()、Thread.join、Thread.sleep、LockSupport.park等方法。 | |||
# 不响应中断的方法:线程进入'''阻塞状态'''后,以及阻塞在'''ReentrantLock.lock方法'''里面的线程,是不响应中断的。 | |||
#: 等待进入synchronized的方法或是代码块,都是会被阻塞的,此时不会响应中断; | |||
#: 可以使用“ReentrantLock.lockInterruptibly”方法响应中断; | |||
=== InterruptedException 处理 === | |||
如果抛出 InterruptedException 意味着一个方法是阻塞方法,那么调用一个阻塞方法则意味着您的方法也是一个阻塞方法,而且您应该有某种策略来处理 InterruptedException。<br/> | |||
对于 '''InterruptedException''': | |||
# 最糟糕的处理方式是 “生吞(swallow)”:即,捕捉它,然后什么也不做(或者记录下它)。 | |||
# |
2020年10月19日 (一) 16:29的版本
中断机制
Java的中断为协作机制,即 A 不能直接中断 B,而是调用 “B.interrupt()” 来申请中断 B (设置中断状态);然后由 B 通过 “interrupted()”(会重置中断状态)或 “isInterrupted()”(不会重置中断状态)读取中断状态,并决定如何响应。
Java的中断:
- 没有可以强制线程终止的方法。
- interrupt 方法用于请求终止线程。
中断相关源码
private volatile Interruptible blocker; //
private final Object blockerLock = new Object(); // 用于synchronized锁定,实现同步安全
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
...
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); // 调用Interruptible对象b 的同步方法
return;
}
}
interrupt0();
}
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
...
private native void interrupt0();
其中:
- “interrupt()” 方法只是调用了“blocker.interrupt()”和“interrupt0()”,并不对线程运行产生影响;
- “blocker”域用于 nio 的中断?【???待查证】
- “interrupt0()” 是一个 native方法,仅用于设置中断标识(其他的);
- “interrupted()”(静态方法)和“isInterrupted()”(实例方法)最终都是调用本地方法“isInterrupted”;
- “isInterrupted”是一个 native方法,用于判断中断标识,并根据参数决定是否重置中断状态;
- 中断标识的使用,都是在native方法中。
中断响应
当线程处在不同的状态下(Running,Blocked,Waiting),响应中断信号的方式不一样:
- 当线程处于非阻塞状态时,可以在自己需要处理中断逻辑的地方,判断中断标示位是否为true,就可以响应处理中断;
- 线程处于阻塞状态时,JVM会让B线程马上抛出异常或被唤醒,从而让B线程可以选择是否响应中断;
响应中断的方法
- 响应中断的方法: 线程进入等待或是超时等待的状态后,调用interrupt方法都是会响应中断的;
- 所以响应中断的方法:Object.wait()、Thread.join、Thread.sleep、LockSupport.park等方法。
- 不响应中断的方法:线程进入阻塞状态后,以及阻塞在ReentrantLock.lock方法里面的线程,是不响应中断的。
- 等待进入synchronized的方法或是代码块,都是会被阻塞的,此时不会响应中断;
- 可以使用“ReentrantLock.lockInterruptibly”方法响应中断;
InterruptedException 处理
如果抛出 InterruptedException 意味着一个方法是阻塞方法,那么调用一个阻塞方法则意味着您的方法也是一个阻塞方法,而且您应该有某种策略来处理 InterruptedException。
对于 InterruptedException:
- 最糟糕的处理方式是 “生吞(swallow)”:即,捕捉它,然后什么也不做(或者记录下它)。