什么是可打断锁

用最简单的语言形容就是,当一个线程去竞争资源的时候,会进入(阻塞/等待)队列,如果可以用一种方法,让它从(阻塞/等待)队列出来,就叫可打断锁。

这里大家容易混淆的就是synchronized中使用sleep和wait被打断了,就觉得synchronized是可打断锁,大家要明白一件事,你的sleep方法和wait方法激活的前提是,你已经获得了synchronized的对象锁了,这时候就意味着你并非在阻塞队列中。

只有在竞争锁的时候,在锁的(阻塞/等待)队列等待时,能被打断的锁,才能叫做可打断锁

下面代码证明synchronized并非可打断锁

public static void main(String[] args) throws InterruptedException {
    Object o = new Object();
    Thread t1 = new Thread(() -> {
        // 直接获得锁
        synchronized (o) {
            try {
                System.out.println("t1获得锁了,开始休眠");
                Thread.sleep(1000000);  //长时间休眠
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    t1.start();
    Thread t2 = new Thread(() -> {
        try {
            Thread.sleep(1000); //先休眠1s保证t1线程一定获得锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 1s后尝试获得锁,发现根本获得不到,会进入阻塞队列等待
        synchronized (o) {
            System.out.println("t2获得锁了");
        }
    });

    Thread.sleep(2000);		//休眠两秒后开始打断在阻塞队列的t2
    System.out.println("打断t2,不让它继续等待");
    t2.interrupt(); // 尝试将t2从阻塞队列打断,结果失效
}

 

ReentrantLock则是可打断锁

public class ReentrantLockTest {
    // 定义锁对象
    private static Lock lock = new ReentrantLock();
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("尝试获得锁");
                // 如果没有竞争,获取锁,有竞争进入阻塞队列,可以被其它线程使用interrupt打断
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("没有获得锁,返回了");
                return;
            }
        }, "t1");
        lock.lock();    //主线程先锁
        t1.start(); //这时候会一直等待并且可被打断
        try {
            Thread.sleep(1000); // 停留1s后,准备打断
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("打断t1");
        t1.interrupt();
    }
}

这里我们也证明一件事,阻塞的队列是不能被打断的,只有等待的队列是可以的!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值