基本使用
interrupt() | 打断某个线程(本质上是设置标志位,并不是直接将线程停止) |
isInterrupted() | 查询某个线程是否被打断(查询标志位) |
static interrupted() | 查询某个线程是否被打断(查询标志位并重置) |
示例程序
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
while (!Thread.interrupted()) {
}
System.out.println("线程被打断!!!");
});
thread.start();
Thread.sleep(1000);
System.out.println("thread.isInterrupted()-1: " + thread.isInterrupted());
// 打断线程
thread.interrupt();
System.out.println("thread.isInterrupted()-2: " + thread.isInterrupted());
Thread.sleep(1000);
System.out.println("thread.isInterrupted()-3: " + thread.isInterrupted());
// 阻塞主线程
System.in.read();
}
运行结果
thread.isInterrupted()-1: false
thread.isInterrupted()-2: true
线程被打断!!!
thread.isInterrupted()-3: false
Process finished with exit code -1
解析
thread.isInterrupted()-1获取到的标志位状态是false,是在thread.interrupt()之前调用,获取到的是默认的标志位
thread.isInterrupted()-2获取到的标志位状态是true,是在thread.interrupt()之后调用,获取到的是当前也就是打断之后的标志位
thread.interrupt()调用之后,Thread.interrupted()得到标志位true结束循环
thread.isInterrupted()-3获取到的标志位状态是false,Thread.interrupted()会重置标志位,所以又获取到的是默认的标志位
interrupt()与sleep()
示例
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("线程被打断!!!");
}
});
thread.start();
Thread.sleep(1000);
// 打断线程
thread.interrupt();
// 阻塞主线程
System.in.read();
}
结果
线程被打断!!!
Process finished with exit code -1
结论
当调用thread.interrupt()后,如果这个线程里面有Thread.sleep()方法,Thread.sleep()会抛出异常InterruptedException
interrupt()与wait()
示例
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
System.out.println("线程被打断!!!");
}
}
}
});
thread.start();
Thread.sleep(1000);
// 打断线程
thread.interrupt();
// 阻塞主线程
System.in.read();
}
结果
线程被打断!!!
Process finished with exit code -1
结论
当调用thread.interrupt()后,如果这个线程里面有this.wait()方法,this.wait()会抛出异常InterruptedException
interrupt()与synchronized
示例
public static void main(String[] args) throws Exception {
Object o = new Object();
Thread thread1 = new Thread(() -> {
synchronized (o) {
System.out.println("线程1抢到锁");
while (true);
}
});
Thread thread2 = new Thread(() -> {
synchronized (o) {
System.out.println("线程2抢到锁");
while (true);
}
});
thread1.start();
// 让线程一先抢锁
Thread.sleep(100);
thread2.start();
Thread.sleep(1000);
// 打断线程
thread1.interrupt();
// 阻塞主线程
System.in.read();
}
结果
线程1抢到锁
结论
线程2一直都没有抢到锁,也就是thread1.interrupt()没有结束线程1的synchronized,所以interrupt()不会打断synchronized
interrupt()与ReentrantLock
示例
public static void main(String[] args) throws Exception {
ReentrantLock lock = new ReentrantLock();
Thread thread1 = new Thread(() -> {
lock.lock();
System.out.println("线程1 start!");
try {
while (true);
} finally {
lock.unlock();
}
});
Thread thread2 = new Thread(() -> {
System.out.println("线程2 start!");
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
System.out.println("线程2被打断了!!!");
}
System.out.println("线程2 end!");
});
thread1.start();
// 让线程一先抢锁
Thread.sleep(100);
thread2.start();
Thread.sleep(1000);
// 打断线程
thread2.interrupt();
// 阻塞主线程
System.in.read();
}
结果
线程1 start!
线程2 start!
线程2被打断了!!!
线程2 end!
Process finished with exit code -1
结论
ReentrantLock的lockInterruptibly()是可以被打断的,interrupt()会让正在抢锁线程抛出异常InterruptedException