• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > ReentrantLock源码分析(三)

ReentrantLock源码分析(三)

作者:XiaoBai_DaShen的博客 字体:[增加 减小] 来源:互联网 时间:2017-08-27

XiaoBai_DaShen的博客通过本文主要向大家介绍了源码,java,锁等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

       本篇重点介绍一下 ReentrantLock 的其他几个重要的方法:

public void lockInterruptibly() throws InterruptedException {
    sync.acquireInterruptibly(1);
}

public boolean tryLock() {
    return sync.nonfairTryAcquire(1);
}

public boolean tryLock(long timeout, TimeUnit unit)
                          throws InterruptedException {
    return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}

void lockInterruptibly()在上一篇的时候已经讲过,它是一个响应中断的获取锁的方法,线程在获取同步状态的过程中如果被中断,直接抛出异常。

二、尝试获取同步状态

       对于 boolean tryLock() 方法,看一下源码:

public boolean tryLock() {
    return sync.nonfairTryAcquire(1);
}

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        if (compareAndSetState(0, acquires)) {
             setExclusiveOwnerThread(current);
             return true;
        }
    }
    else if (current == getExclusiveOwnerThread()) {
         int nextc = c + acquires;
         if (nextc < 0) // overflow
             throw new Error("Maximum lock count exceeded");
         setState(nextc);
         return true;
    }
    return false;
}

       第二个方法是 AbstractQueuedSynchronizer 类中的方法。如果同步状态没有被其他线程获取,则当前线程直接获取,并返回 true,否则获取同步状态失败,返回 false。也就是说这是一个非阻塞的获取锁的方式,不能获取锁时,并不进入同步队列中,而是直接返回。比较简单。

三、超时获取同步状态

       老样子,看源码:

public boolean tryLock(long timeout, TimeUnit unit)
                          throws InterruptedException {
                          //响应中断的
    return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}

public final boolean tryAcquireNanos(int arg, long nanosTimeout)
                                throws InterruptedException {   
    if (Thread.interrupted())
        throw new InterruptedException();
    //先获取同步状态,成功直接返回,
    //失败的话执行 doAcquireNanos(arg, nanosTimeout)
    return tryAcquire(arg) ||
        doAcquireNanos(arg, nanosTimeout);
}

private boolean doAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
    //等待时间小于等于0的话,直接返回false,获取失败。
    if (nanosTimeout <= 0L)
        return false;
    //计算截止时间
    final long deadline = System.nanoTime() + nanosTimeout;
    //加入同步队列中
    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 true;
            }
            //获取同步状态失败的话,计算剩余时间
            nanosTimeout = deadline - System.nanoTime();
            //如果剩余时间没了,返回false,获取失败。
            if (nanosTimeout <= 0L)
                return false;
            //如果还剩下时间的话,检查是否可以进入waiting状态
            // 并检查剩余时间知否大于spinForTimeoutThreshold
            if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                //park线程,线程等待时长为剩余时间大小
                LockSupport.parkNanos(this, nanosTimeout);
                if (Thread.interrupted())    //响应中断
                    throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

分析都在代码中,也是比较简单的。
       这一篇比较简单哈。ReentrantLock 就写到这吧,当然,还有一个构件 Condition,以后有机会再写。

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • ReentrantLock源码分析(三)
  • ReentrantLock源码分析(二)
  • 认证流程源码级详解
  • PipedWriter和PipedReader源码分析_动力节点Java学院整理
  • Java微信公众号开发之通过微信公众号获取用户信息
  • Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理
  • MyBatis的嵌套查询解析
  • java向文件中追加内容与读写文件内容源码实例代码
  • java异常处理详细介绍及实例
  • struts1实现简单的登录功能实例(附源码)

相关文章

  • 2017-05-28Java方法重写_动力节点Java学院整理
  • 2017-05-28Java HTTP协议收发MQ 消息代码实例详解
  • 2017-05-28Netty学习教程之基础使用篇
  • 2017-05-28深入理解hibernate的三种状态
  • 2017-05-28详解Java中-classpath和路径的使用
  • 2017-05-28SpringBoot定义过滤器、监听器、拦截器的方法
  • 2017-05-28java生成缩略图的方法示例
  • 2017-05-28基于SpringBoot与Mybatis实现SpringMVC Web项目
  • 2017-05-28深入理解Spring MVC概要与环境配置
  • 2017-05-28Java多线程并发编程 Synchronized关键字

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 详解Spring+Hiernate整合
    • Spring Boot中整合Spring Security并自定义验证代码实例
    • 详解 Java 中 equals 和 == 的区别
    • Mybatis传list参数调用oracle存储过程的解决方法
    • Java经验点滴:处理没有被捕获的异常
    • spring boot下 500 404 错误页面处理的方法
    • Java关键字this(动力节点Java学院整理)
    • 详解Spring-Boot中如何使用多线程处理任务
    • SpringMVC之简单的增删改查示例(SSM整合)
    • servlet监听实现统计在线人数功能 附源码下载

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有