1、interrupt相关的三个方法:
//Thread.java
public void interrupt() //t.interrupt() 打断t线程(设置t线程某给标志位f=true,并不是打断线程的运行)
public boolean isInterrupted() //t.isInterrupted() 查询打断标志位是否被设置(是不是曾经被打断过)
public static boolean interrupted()//Thread.interrupted() 查看“当前”线程是否被打断,如果被打断,恢复标志位
- interrupt() :实例方法,设置线程中断标志
interrupt()方法是Thread类的实例方法,用于中断当前线程或指定线程。- 调用
interrupt()方法会将线程的中断状态设置为true。 - 如果线程处于阻塞状态(如
sleep、wait、join等),那么调用interrupt()方法会立即抛出InterruptedException异常。 - 如果线程处于非阻塞状态,
interrupt()方法仅会将线程的中断状态设置为true,具体的中断行为需要线程自行处理。
- isInterrupted():实例方法
isInterrupted()方法是Thread类的实例方法,用于检查线程的中断状态。- 调用
isInterrupted()方法会返回线程的中断状态,即是否被中断。 - 该方法不会清除线程的中断状态。
- interrupted():静态方法
interrupted()方法是Thread类的静态方法,用于检查当前线程的中断状态,并且会清除中断状态。- 调用
interrupted()方法会返回当前线程的中断状态,即是否被中断。 - 与
isInterrupted()方法不同,interrupted()方法会清除当前线程的中断状态。
2、准备工具类,控制线程的睡眠时间
public static class SleepHelper {
public static void sleepSeconds(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void sleepMilli(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3、知识点讲解及代码示例
1)、interrupt方法的使用和interrupted的使用
//===================================================
// 打断某个线程,设置标志位
Thread t1 = new Thread(()->{
for (;;){
if (Thread.currentThread().isInterrupted()){
System.out.println("Thread is interrupted! now State is " + Thread.currentThread().getState());
System.out.println(Thread.currentThread().isInterrupted());
break;
}
}
});
t1.start();
SleepHelper.sleepSeconds(2);
t1.interrupt();
//===================================================
// interrupted检查线程是否打断过,
// 如果打断过,重置标志位
Thread t2 = new Thread(() -> {
for (; ; ) {
if (Thread.interrupted()) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.interrupted());
}
}
});
t2.start();
SleepHelper.sleepSeconds(2);
t2.interrupt();
// 如果在这里写
// 输出的是主线程的中断状态
System.out.println("main: " + t2.interrupted());
2)、interrupt和sleep() wait() join()
sleep()方法在睡眠的时候,不到时间是没有办法叫醒的,这个时候可以用interrupt设置标志位,然后必须catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)
- 下方是代码示例
//===================================================
// interrupt不能打断进程的sleep状态
// 必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)
Thread t3 = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
});
t3.start();
SleepHelper.sleepSeconds(5);
t3.interrupt();
//===================================================
// interrupt不能打断进程的wait状态
// 必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)
Thread t4 = new Thread(() -> {
synchronized (o) {
try {
o.wait();
} catch (InterruptedException e) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
}
});
t4.start();
SleepHelper.sleepSeconds(5);
t4.interrupt();
3)、interrupt不能中断正在竞争锁的线程
//===================================================
// interrupt不能中断正在竞争锁的线程
// 下面证明interrupt不能中断正在synchronized竞争锁的线程
Thread t5_1 = new Thread(() -> {
synchronized (o) {
SleepHelper.sleepSeconds(10);
}
});
t5_1.start();
SleepHelper.sleepSeconds(1);
Thread t5_2 = new Thread(() -> {
synchronized (o) {
}
System.out.println("t2 end!");
});
t5_2.start();
SleepHelper.sleepSeconds(1);
t5_2.interrupt();
//===================================================
// interrupt不能中断正在竞争锁的线程
// 下面证明interrupt不能中断正在lock竞争锁的线程
Thread t6_1 = new Thread(() -> {
lock.lock();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t6_1.start();
SleepHelper.sleepSeconds(1);
Thread t6_2 = new Thread(() -> {
lock.lock();
try {
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t6_2.start();
SleepHelper.sleepSeconds(1);
t6_2.interrupt();
4)、如果想打断正在竞争锁的线程,使用ReentrantLock的lockInterruptibly()
//===================================================
// 如果想打断正在竞争锁的线程,使用ReentrantLock的lockInterruptibly()
Thread t7_1 = new Thread(() -> {
lock.lock();
try {
SleepHelper.sleepSeconds(10);
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t7_1.start();
SleepHelper.sleepSeconds(1);
Thread t7_2 = new Thread(() -> {
System.out.println("t2 start!");
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t7_2.start();
SleepHelper.sleepSeconds(1);
t7_2.interrupt();
5)、整体代码
public static void main(String[] args) throws Exception {
Object o = new Object();
ReentrantLock lock = new ReentrantLock();
//===================================================
// 打断某个线程,设置标志位
Thread t1 = new Thread(()->{
for (;;){
if (Thread.currentThread().isInterrupted()){
System.out.println("Thread is interrupted! now State is " + Thread.currentThread().getState());
System.out.println(Thread.currentThread().isInterrupted());
break;
}
}
});
t1.start();
SleepHelper.sleepSeconds(2);
t1.interrupt();
//===================================================
// interrupted检查线程是否打断过,
// 如果打断过,重置标志位
Thread t2 = new Thread(() -> {
for (; ; ) {
if (Thread.interrupted()) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.interrupted());
}
}
});
t2.start();
SleepHelper.sleepSeconds(2);
t2.interrupt();
// 如果在这里写
// 输出的是主线程的中断状态
System.out.println("main: " + t2.interrupted());
//===================================================
// interrupt不能打断进程的sleep状态
// 必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)
Thread t3 = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
});
t3.start();
SleepHelper.sleepSeconds(5);
t3.interrupt();
//===================================================
// interrupt不能打断进程的wait状态
// 必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)
Thread t4 = new Thread(() -> {
synchronized (o) {
try {
o.wait();
} catch (InterruptedException e) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
}
});
t4.start();
SleepHelper.sleepSeconds(5);
t4.interrupt();
//===================================================
// interrupt不能中断正在竞争锁的线程
// 下面证明interrupt不能中断正在synchronized竞争锁的线程
Thread t5_1 = new Thread(() -> {
synchronized (o) {
SleepHelper.sleepSeconds(10);
}
});
t5_1.start();
SleepHelper.sleepSeconds(1);
Thread t5_2 = new Thread(() -> {
synchronized (o) {
}
System.out.println("t2 end!");
});
t5_2.start();
SleepHelper.sleepSeconds(1);
t5_2.interrupt();
//===================================================
// interrupt不能中断正在竞争锁的线程
// 下面证明interrupt不能中断正在lock竞争锁的线程
Thread t6_1 = new Thread(() -> {
lock.lock();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t6_1.start();
SleepHelper.sleepSeconds(1);
Thread t6_2 = new Thread(() -> {
lock.lock();
try {
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t6_2.start();
SleepHelper.sleepSeconds(1);
t6_2.interrupt();
//===================================================
// 如果想打断正在竞争锁的线程,使用ReentrantLock的lockInterruptibly()
Thread t7_1 = new Thread(() -> {
lock.lock();
try {
SleepHelper.sleepSeconds(10);
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t7_1.start();
SleepHelper.sleepSeconds(1);
Thread t7_2 = new Thread(() -> {
System.out.println("t2 start!");
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t7_2.start();
SleepHelper.sleepSeconds(1);
t7_2.interrupt();
}