个人理解
来源:4-6 遭遇面试官深度问synchronized的本质

iiiboy
2021-03-18
public static void main(String[] args) throws InterruptedException {
ReentrantLock rLock = new ReentrantLock();
Thread rThread = new Thread(() -> {
try {
rLock.lockInterruptibly();
// 检测线程是否中断
for (int i = 0; i < 1000000 && !Thread.currentThread().isInterrupted(); i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
}
} catch (InterruptedException e) {
System.out.println("获取锁的过程中被中断了");
e.printStackTrace();
} finally {
rLock.unlock();
}
});
rThread.start();
TimeUnit.MILLISECONDS.sleep(1);
rThread.interrupt();
}
老师的代码演示的是ReentrantLock lockInterruptibly方法在获取锁的过程中是可以被中断的
但是如果线程已经获取到锁,想要中断线程还是需要使用isInterrupted检测线程是否被中断
个人理解:
线程都是可以被中断的(需要检测或者响应中断),这Thread类的能力,与使用synchronized、ReentrantLock无关
但是线程在获取锁的过程中:
获取synchronized锁的过程中,线程是不能被中断的
使用ReentrantLock的lockInterruptibly方法在获取锁的过程中,线程是可以被中断的
如有不对,还望老师指正
3回答
-
牛牛同学
2021-05-01
运行的程序不会立刻中断停止,为了防止数据不一致的问题。而阻塞的程序会响应中断,这是靠阻塞方法自己实现的,内部包含检测过程,比较sleep和wait内部会检测中断。
00 -
求老仙
2021-03-18
其实你可以再思考下为什么java不能触发interrupt就马上中断
042021-03-19 -
求老仙
2021-03-18
赞!特别好的一个问题。
Thread.interrupt()设置的是Thread的一个flag,InterruptException只在两种情况下被抛出:
当前线程处于休眠(Thread.sleep)等待(object.wait)等状态下被
主动抛出。
ReentrantLock属于主动抛出的情况,就是调用lockInterruptibly检查flag然后抛出。所以如果有线程只调用了一次lockInterruptibly,然后被interrupt,那么是不会抛出InterruptException的,
你可以自己试试,下面这个程序永远无法结束:
var t = new Thread(() -> { try { lock.lockInterruptibly(); while(true); } catch (InterruptedException e) { e.printStackTrace(); } }); t.start(); Thread.sleep(100); t.interrupt(); t.join();
但是如果while循环处改成
while(true) { lock.lockInterruptibly(); }
线程就会异常退出。
你可以再改下:
while(true) { Thread.sleep(100); }
这个程序也是可以正常响应interrupt的。
012021-06-08
相似问题