Interrupt相关方法
Interrupt方法
public void interrupt()
interrupt方法用来设置线程打断标志,但不会修改线程的运行状态
isInterrupted方法
public boolean isInterrupted()
实例方法,用来获取线程是否被设置打断标志
interrupted方法
public static boolean interrupted()
静态方法,用来获取进程打断标志,同时会清除打断标志
Interrupt与sleep/wait
线程sleep过程中如果被打断,会抛出异常 InterruptedException,sleep会提前结束,并且此时线程的打断标志会被清除。如果需要在被打断时做出响应,可以捕获异常后处理。
public class InterruptSleep {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("catch interrupted exception ");
System.out.println(Thread.currentThread().isInterrupted());
}
});
t.start();
SleepHelper.sleep(1000);
t.interrupt();
}
}
/** 1秒后程序会结束
catch interrupted exception
false
Process finished with exit code 0
*/
wait的效果和sleep很相似。
interrupt与synchronized
interrupt无法干扰正在阻塞等待 synchronized 锁的线程
public class InterruptSynchronized {
static Object o = new Object();
public static void main(String[] args) {
Thread t = new Thread(() -> {
synchronized (o) {
System.out.println("thread got lock");
}
});
new Thread(() -> {
synchronized (o) {
SleepHelper.sleep(10000);
}
}).start();
SleepHelper.sleep(1000);
t.start();
t.interrupt();
}
}
/** 10秒后输出
thread got lock
Process finished with exit code 0
*/
interrupt与lock
interrupt无法打断等待lock锁的线程
public class InterruptLock {
static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
lock.lock();
System.out.println("t got lock");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
new Thread(() -> {
lock.lock();
SleepHelper.sleep(10000);
lock.unlock();
}).start();
SleepHelper.sleep(1000);
t.start();
t.interrupt();
}
}
/** 10秒后输出
t got lock
Process finished with exit code 0
*/
如果需要线程等待锁的过程中可以被打断,使用 lockInterruptibily
public class InterruptLock {
static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
lock.lockInterruptibly();
System.out.println("t got lock");
} catch (Exception e) {
System.out.println("t got interrupted");
} finally {
lock.unlock();
}
});
new Thread(() -> {
lock.lock();
SleepHelper.sleep(10000);
lock.unlock();
}).start();
SleepHelper.sleep(1000);
t.start();
t.interrupt();
}
}
/** 1秒后输出
t got interrupted
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at org.example.juc.InterruptLock.lambda$main$0(InterruptLock.java:20)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
*/
小结
interrupt可以通过设置线程的中断状态来达到通知的目的,具体是否需要做出响应可以视情况而定。比如想在线程外部终止线程的执行而又不破坏数据一致性,比如多线程争抢锁并操作数据的情况,可以利用interrupt来通知线程,线程内部通过中断状态来优雅的终止,而不是强制杀死线程。