interrupt概念
interrupt翻译成中文为“打断”的意思,但实际上,interrupt()方法并非将一个线程打中断的意思。查看Thread.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();
}
从以上源码可以知道,interrupt()方法只是设置了Thread对象中的一个标志位而已(Just to set the interrupt flag)。它的意义在于,线程可以通过这个标志位来决定需要做什么操作。
interrupt相关方法
- interrupt()
打断某个线程(设置标志位) - isInterrupted()
查询某个线程是否被打断过(查询标志位) - interrupted()
查询当前线程是否被打断过,并重置标志位
public class TestThread {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("Thread is interrupted");
System.out.println(Thread.currentThread().isInterrupted());
}
});
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
输出如下:
Thread is interrupted
false
可知当线程sleep时,如果调用了interrupt()方法,将会抛出InterruptedException异常。捕获异常之后,会重置interrupt标志位。
wait、sleep、join与interrupt
当一个线程在wait、sleep或join时,如果调用了其interrupt()方法,则会抛出InterruptedException异常。
synchronized与interrupt
当一个线程在等待锁的时候,其能否被interrupt打断?
public class TestThread {
public static void main(String[] args) {
final Object o = new Object();
new Thread(() -> {
synchronized (o) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread thread = new Thread(() -> {
System.out.println("thread 获得锁");
});
thread.start();
thread.interrupt();
}
}
输出:
thread 获得锁
可知当线程等待锁时,并不会被打断。
ReentrantLock与interrupt
public class TestThread {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
lock.lock();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
});
Thread t2 = new Thread(() -> {
lock.lock();
System.out.println("t2 获得锁");
lock.unlock();
});
t1.start();
t2.start();
t2.interrupt();
}
}
输出:
t2 获得锁
此时,线程在lock等待时依然不会被打断。如果希望线程在lock等待时可以被打断,可使用lockInterruptibly方法。