线程阻塞可以采用Object.wait()、Object.notify()来控制线程的阻塞唤醒。
另一种方式是调用Unsafe.park()、Unsafe.unpark()。
在主动调用线程interrupt方法之后,目标线程如果正在block状态就会被唤醒,通过Object.wait()、Unsafe.park()控制的阻塞都会被唤醒并直接往下执行,但是如果执行后面的逻辑中再次碰到Object.wait()就会再次被阻塞,而如果是碰到Unsafe.park()线程则会直接往下执行。测试代码如下
public class InterruptTest {
public static void main(String[] args) {
String t1b = "t1 block";
final Thread t1 = new Thread(()->{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000000; i++) {
sb.append(i ^ 100);
}
try {
synchronized (t1b) {
t1b.wait();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(1);
LockSupport.park(t1b);//park 在线程被标识为interrupt之后会直接往下执行
//Object.wait() 在线程标识为interrupt之后还是会阻塞
try {
synchronized (t1b) {
t1b.wait();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(2);
});
t1.start();
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//线程如果正在wait、sleep中会直接抛出一个InterruptedException异常并且往下执行,如果再次碰到wait、sleep那还是会被阻塞
//线程如果是RUNNING状态,之后第一次遇到wait或者sleep也会抛出InterruptedException异常并且往下执行,但是再次遇到wait、sleep时还是会被阻塞
//如果是park则都会直接跳过并且不抛出异常
t1.interrupt();
}