`
suichangkele
  • 浏览: 199745 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lock与lock.lockInterruptibly源码解读

    博客分类:
  • java
阅读更多

f双方都

在重入锁(ReentrantLock)中,有两个相似的方法,一个是lock,一个是lockInterruptably,之前没有细看,之前我一直用的是lock,不过最近再看公司的代码时,发现有人竟然用的是后者,于是我就好奇了,特么的到底哪里不一样,于是跟了下源码,特此记录一下。(ReentrantLock使用aqs实现的,最好先看懂aqs再来搞重入锁)。

再lock中,最终调用的是:java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(int)方法,

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&//尝试获得锁,失败时返回false
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//入队列,然后挂起线程,我们重点看一下这个方法
            selfInterrupt();
    }

挂起线程的方法

final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&//判断是否应该park
                    parkAndCheckInterrupt())//park当前的线程
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
}

 挂起当前的线程的代码,在挂起一定时间后,返回的是当前的线程是否有interruptted的状态

private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}

 从上面的代码可以看出,如果某个线程在等待锁的时候别interrupt了,那么在获得锁之后,就会在acquireQueued方法中返回true,然后我们回到acquire中,在上面的parkAndCheckInterrupt方法返回true之后(也就是当前的线程是被interrupt了),就会进入selfInterrupt方法,里面很简单,就一句

private static void selfInterrupt() {
   Thread.currentThread().interrupt();//自己调用interrupt方法,但是这样不会有任何的作用,也就是直接忽略了在等待的时候别的线程对当前线程的interrupt操作。
}

 从上面的分析中,我们得到结论,lock方法中会忽略在当前线程被park的时候其他线程堆当前线程的interrupt方法,不会有任何操作。

 

我们再分析一下,lockInterruptably方法,他在尝试获取锁失败后,会进入这个方法:

    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())//从上面的代码分析中,我们已经知道了,当当前的线程在park之后,如果当前的线程被interrupt之后,就会返回true,那么就会进入if,即抛出一个interruptedException。
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

 从上面的分析中,我们便知道了,lockInterruptably,会在park之后,抛出一个异常,这就是区别

 

so easy!!!

 

 

 

 

分享到:
评论

相关推荐

    linux 内核mutex.c 源码分析实例

    linux 内核 mutex.c 源码分析实例,我的实例主要先初始化了一个互斥体m,然后获取互斥体的锁(解锁),紧接着释放互斥体的锁(解锁)。最后释放互斥体。中间通过输出m.count来显示互斥体的状态。

    Lock SELinux forced mode.zip

    标题“Lock SELinux forced mode.zip”暗示了这个压缩包与Linux系统的安全增强层(Security-Enhanced Linux,简称SELinux)有关,特别是涉及到强制模式(forced mode)的配置。在这个场景下,SELinux是一个内核模块...

    Lock-in Amplifier.pdf

    significance of a lock-in amplifier. As an introduction to the subject there follows a simple intuitive account biased towards light measurement applications. All lock-in amplifiers, whether ...

    X99 Professional Gaming i7 lock-70mv.zip

    X99 Professional Gaming i7 lock-70mv.zip

    精彩编程与编程技巧-设定CapsLock ScrollLock NumLock...

    ### 知识点:使用API控制CapsLock、ScrollLock、NumLock键状态 #### 一、概述 在软件开发过程中,有时需要通过程序控制键盘上的一些特殊按键的状态,例如CapsLock(大写锁定)、ScrollLock(滚动锁定)以及NumLock...

    实现yarnlock与packagelockjson相互转换

    `package-lock.json` 文件则是npm 5及更高版本引入的特性,它的功能与`yarn.lock`类似,也是用来锁定项目依赖的具体版本。每当`npm install`执行时,如果`package-lock.json`不存在,它会被创建;如果已存在,npm会...

    易语言源码易语言lock挂机锁源码.rar

    "易语言lock挂机锁源码"是指使用易语言编写的,用于实现挂机锁功能的源代码。挂机锁通常是一种软件保护机制,它可以防止未经授权的用户在无人操作时继续使用计算机或软件,确保软件使用的安全性和合法性。 挂机锁的...

    java的Lock锁原理详解.docx

    lock.lock(); // 获取锁 Thread thread = new Thread(() -> { try { lock.unlock(); // 释放锁 lock.lock(); // 再次获取锁 System.out.println("拿到锁"); lock.unlock(); // 释放锁 System.out.println(...

    计算机软件-商业源码-实例92 检测NumLock、Insert、CapsLock、ScrollLock键的状态.zip

    在计算机编程领域,有时我们需要获取键盘上特殊功能键的状态,比如NumLock、Insert、CapsLock和ScrollLock。这些键在日常使用中并不常被按下,但它们的状态对于某些特定的应用程序,如数据输入或者特殊控制,是至关...

    X99 Professional lock-70mv.zip

    标题“X99 Professional lock-70mv.zip”暗示了我们正在处理与X99专业主板相关的固件或 BIOS 更新。X99是Intel推出的一个芯片组,主要针对高端多核处理器,如Intel Core i7 Extreme Edition系列。"lock-70mv"可能是...

    X99 OC Formula lock-70mv.zip

    【X99 OC Formula lock-70mv.zip】是一个针对X99平台的超频工具包,主要用于优化和提升Intel X99芯片组主板的性能。"OC"是Overclocking的缩写,指的是通过手动调整硬件参数来超越制造商规定的默认工作频率,以提高...

    Python应用实战:python多线程-多线程安全问题&lock与rlock.zip

    在Python中,`threading.Lock`类可以创建一个基本的锁对象。当你需要保护一段代码不被多个线程同时执行时,可以使用`acquire()`方法获取锁,执行完关键代码后用`release()`方法释放锁。 ```python import threading...

    Lock_TryLock.rar

    `Lock_TryLock.rar`这个压缩包文件显然包含了一个关于如何在QT中使用`QMutex`的实例,尤其是关注`lock()`, `trylock()`和`QMutexLocker`的使用。下面将详细讲解这三个关键功能及其区别。 1. **QMutex::lock()**: 这...

    解决git:fatal:Unable to create”…/.git/index.lock” 的错误

    报错大致意思就是创建index.lock文件失败,因为已经存在index.lock文件了. index.lock文件是在.git下面, 而.git是一般是隐藏的, 那么可以通过以下命令删除即可. rm -rf /Users/dianji/project/ccpay.h5/.git/index....

    易语言lock挂机锁源码.zip

    通过对易语言lock挂机锁源码的学习,开发者不仅可以掌握易语言的基础编程技巧,还能深入理解多线程同步和资源管理的关键概念,这对于进行多用户应用或网络服务的开发至关重要。此外,了解并分析这样的源码还可以帮助...

    将yarn.lock转换为package-lock.json,反之亦然-JavaScript开发

    install npm install -g synp命令行用法yarn.lock => package-lock.json yarn#确保node_modules文件夹目录并已更新synp --source-file /path/to/yarn.lock#将创建/ path / to / package-lock.json package-lock....

    SWF, Lock & Load 1.206 汉化版

    SWF, Lock & Load 是一个专门针对Adobe Flash(SWF文件)开发的工具,主要用于创建和集成预加载器。在互联网上,Flash内容常用于制作动态网页元素和交互式应用程序,但大型的Flash文件可能会导致页面加载缓慢,用户...

    潮5000 CFG Lock 解锁工具包.zip

    这个工具会与BIOS进行交互,更改相关设置,使得用户可以在BIOS设置中启用或禁用CFG Lock。 3. **使用说明**:为了确保用户正确、安全地使用这些工具,工具包可能还包括详细的步骤说明或视频教程。这至关重要,因为...

    Python库 | yg.lockfile-2.2.1.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:yg.lockfile-2.2.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

Global site tag (gtag.js) - Google Analytics