个人理解

来源: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内部会检测中断。

0
0

求老仙

2021-03-18

其实你可以再思考下为什么java不能触发interrupt就马上中断

0
4
求老仙
中断是强制执行的
2021-03-19
共4条回复

求老仙

2021-03-18

赞!特别好的一个问题。

Thread.interrupt()设置的是Thread的一个flag,InterruptException只在两种情况下被抛出:

  1. 当前线程处于休眠(Thread.sleep)等待(object.wait)等状态下被

  2. 主动抛出。

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的。 

0
1
大东来提高
没事了老师 我看错了
2021-06-08
共1条回复

笑傲Java面试 剖析大厂高频面试真题 秒变offer收割机

深度剖析大厂面试高频真题,让你秒变offer收割机

1783 学习 · 314 问题

查看课程