zoukankan      html  css  js  c++  java
  • 关于ReentrantLock 中的lockInterruptibly方法的简单探究

    今天在看Lock,都知道相比于synchronized,多了公平锁,可中断等优秀性能。

    但是说到可中断这个特点,看到很多博客是这么描述的:

    “与synchronized关键字不同,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会被释放”

    我的理解是,应该是未获得到锁的线程被中断时,中断异常将会被抛出。

    看了下lockInterruptibly()的源码

    第一层

    public void lockInterruptibly() throws InterruptedException {

        sync.acquireInterruptibly(1);
    }
    第二层
    public final void acquireInterruptibly(int arg)
    throws InterruptedException {
    if (Thread.interrupted())
    throw new InterruptedException();
    if (!tryAcquire(arg))
    doAcquireInterruptibly(arg);
    }
    第3层
    private void doAcquireInterruptibly(int arg)
    throws InterruptedException {
    final Node node = addWaiter(Node.EXCLUSIVE);
    boolean failed = true;
    try {
    for (;;) {
    final Node p = node.predecessor();
    if (p == head && tryAcquire(arg)) {
    setHead(node);
    p.next = null; // help GC
    failed = false;
    return;
    }
    if (shouldParkAfterFailedAcquire(p, node) &&
    parkAndCheckInterrupt())
    throw new InterruptedException();
    }
    } finally {
    if (failed)
    cancelAcquire(node);
    }
    }


    其实就是调用lockInterruptibly()时,第二层中判断当前线程是否中断Thread.interrupted() 如果是,抛异常
    以及第三层中 一个for(;;)循环一直判断当前线程是否有中断标志。(代码中大字标识部分)

    所以不是很理解很多博客中说的这种情况。


    总结:lock中的可中断特性是基于lockInterruptibly()方法的,它是对于那些未竞争的到锁,而 可以被外部调用interrupt()来中断,从而达到不在等候锁资源,不再去竞争锁
  • 相关阅读:
    Java数据库操作(MySQL与SQLserver)
    LeetCode 11. 盛最多水的容器
    LeetCode 10.正则表达式匹配
    LeetCode 9.回文数
    LeetCode 7. 整数反转
    LeetCode 6.Z 字形变换
    LeetCode 4.寻找两个正序数组的中位数
    LeetCode 3. 无重复字符的最长子串
    JOI2020遗迹
    线性规划对偶
  • 原文地址:https://www.cnblogs.com/xlblog/p/11531191.html
Copyright © 2011-2022 走看看