第七章 ReentrantLock总结

常用方式:

        int a = 12;
        //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁
        final ReentrantLock lock = new ReentrantLock();

        lock.lock();//获取锁
        try {
            a++;//业务逻辑
        } catch (Exception e) {
        }finally{
            lock.unlock();//释放锁
        }

1、非公平锁获取锁的步骤lock()

基于CAS尝试将state(锁数量)从0设置为1

A、如果设置成功,设置当前线程为独占锁的线程;

B、如果设置失败,还会再获取一次锁数量,

B1、如果锁数量为0,再基于CAS尝试将state(锁数量)从0设置为1一次,如果设置成功,设置当前线程为独占锁的线程;

B2、如果锁数量不为0或者上边的尝试又失败了,查看当前线程是不是已经是独占锁的线程了,如果是,则将当前的锁数量+1;

如果不是,则将该线程封装在一个Node内,并加入到等待队列中去。等待被其前一个线程节点唤醒。

2、公平锁获取锁的步骤lock()

获取一次锁数量,

B1、如果锁数量为0,如果当前线程是等待队列中的头节点,基于CAS尝试将state(锁数量)从0设置为1一次,如果设置成功,设置当前线程为独占锁的线程;

B2、如果锁数量不为0或者当前线程不是等待队列中的头节点或者上边的尝试又失败了,查看当前线程是不是已经是独占锁的线程了,如果是,则将当前的锁数量+1;如果不是,则将该线程封装在一个Node内,并加入到等待队列中去。等待被其前一个线程节点唤醒。

3、解锁的步骤

1)获取当前的锁数量,然后用这个锁数量减去解锁的数量(这里为1),最后得出结果c

2)判断当前线程是不是独占锁的线程,如果不是,抛出异常

3)如果c==0,说明锁被成功释放,将当前的独占线程置为null,锁数量置为0,返回true

4)如果c!=0,说明释放锁失败,锁数量置为c,返回false

5)如果锁被释放成功的话,唤醒距离头节点最近的一个非取消的节点

4、ReentrantLock的其他方法

除了上边几个常用的方法,我下边列出其余的2个比较好的方法。

    /**
     * 四点注意:
     * 1、如果其他线程没有持有这个锁,立即返回true,设置锁的数量为1
     * 2、如果当前线程已经持有这个锁了,那么锁数量+1,立即返回true
     * 3、如果其他线程占有这个锁,该方法立即返回false
     * 4、要注意:这个锁是非公平锁(即无法用于公平锁策略中)
     */
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }

    /**
     * 在指定时间内这个锁某个时刻没有被其他线程占有并且当前线程没有被中断,获得这个锁
     *
     * 1)如果没有其他线程占有这个锁,则获得这个锁,立即返回true,锁数量+1
     * 2)如果当前线程已经持有这个锁了,那么锁数量+1,立即返回true
     * 3)如果这个锁被其他线程持有,当前线程阻塞,直到下面三种情况发生:
     * A、当前线程(被唤醒后)成功的获取锁
     * B、其他线程中断了当前线程
     * C、指定时间超时(如果时间<=0,根本就不会等待)
     *
     * 如果该锁被用于公平锁:如果有其他线程在等待,即使判断出没有其他线程占有这个锁,当前线程也不会获取这个锁
     */
    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

时间: 2024-10-06 14:41:35

第七章 ReentrantLock总结的相关文章

第七章定制并发类

Java 7 并发编程实战手册目录 代码下载(https://github.com/Wang-Jun-Chao/java-concurrency) 第七章定制并发类 7.1简介 Java并发API提供了大量接口和类来实现并发应用程序.这些接口和类既包含了底层机制,如Thread类.Runnable接口或Callable接口.synchronized关键字,也包含了高层机制,如在Java 7中增加的Executor框架和Fork/Join框架.尽管如此,在开发应用程序时,仍会发现己有的Java类无

第七章

第七章 控制发光二极管. 尽管linux 驱动直接和硬件打交道,但并不是linux驱动直接向硬件中的内存写数据,而是与本机的i/o内存进行交互.所谓I/O内存是通过各种接口(PCI, USB.蓝牙以太网等)连接到主机的硬件在主机的内存映射.Linux内核提供了多个与I/O内存交互的函数.Linux内核的内存管理模块负责同步I/O内存与硬件的数据. 每一个连接Linux 的硬件在I/O内存中都会有映射首地址.在使用ioread 32.ioread32等函数读写I/O内存时需要指定这些首地址.Led

第七章:常用类

第七章:常用类 包装类 java中有8中基本类型,对应有八种包装类作用:包装类中封装了该类型常用的属性和方法,以方便操作.byte---->Byteshort--->Shortint--->Integerlong---->Longfloat---->Floatdouble---->Doublechar---->Characterboolean---->Boolean装箱:将基本数据类型转换成包装类,经常通过构造方法完成.Integer i = new Int

构建之法学习(第七章 MSF)

第七章 MSF MSF(Microsoft Solution Framework)微软解决方案框架: MSF是一套大型系统开发指南,是微软推荐的软件开发方法,它描述了如何用组队模型.过程模型和应用模型来开发Client/Server结构的应用程序,是在微软的工具和技术的基础上建立并开发分布式企业系统应用的参考. 一.MSF 9条基本原则 1.推动信息共享与沟通 --把所有信息都保留并公开,讨论要包括所有涉及的角色,决定要公开并告知所有人. 当然,对牵涉到技术机密.安全性等信息要采取必要的保护措施

Android开发艺术探索——第七章:Android动画深入分析

Android开发艺术探索--第七章:Android动画深入分析 Android的动画可以分成三种,view动画,帧动画,还有属性动画,其实帧动画也是属于view动画的一种,,只不过他和传统的平移之类的动画不太一样的是表现形式上有点不一样,view动画是通过对场景的不断图像交换而产生的动画效果,而帧动画就是播放一大段图片,很显然,图片多了会OOM,属性动画通过动态的改变对象的属性达到动画效果,也是api11的新特性,在低版本无法使用属性动画,但是我们依旧有一些兼容库,OK,我们还是继续来看下详细

第九章 前七章总结考试答案

前七章总结测验见附件内容

ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse

ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. 提供ROS接口的3D软件比较多,本章以最典型的Gazebo介绍为主,从Player/Stage/Gazebo发展而来,现在独立的机器人仿真开发环境,目前2016年最新版本Gazebo7.1配合ROS(kinetic)使用. 补充内容:http://blo

构建之法第六、七章读后感

第六章 Scrum 是一个用于开发和维持复杂产品的框架 ,是一个增量的.迭代的开发过程.Scrum包括了一系列实践和预定义角色的过程骨架.Scrum中的主要角色包括同项目经理类似的Scrum主管角色负责维护过程和任务,产品负责人代表利益所有者,开发团队包括了所有开发人员. 敏捷流程一共有4步: 第一步:弄懂需求与任务是相互依赖的关系 第二步:想要学会把一个任务从产品层级的描述逐步细化到技术实现层面,那么技术能力和交流能力尤为重要的,根据每个人的能力来分配任务以保证任务的高效完成. 第三步:个人要

CSS3秘笈:第七章

第七章  margin.padding和border 1.盒模型:四个属性: (1)padding:内容与其边框线之间的空间. (2)border:盒子周围的直线 (3)background-color:用来填充边框内部空间的,包括padding区域. (4)margin:一个标签和另一个标签之间的间隔. 2.padding和margin的区别:padding是在内容和边框之间增加空间.避免内容被硬塞在方框里面,它还包括背景区域,因此padding占用的空间也可以为空白的内容.而margin则是