常用方式:

        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内,并加入到等待队列中去,然后挂起park。等待被其前一个线程节点唤醒。

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

获取一次锁数量,

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

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

3、解锁的步骤

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

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

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

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

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

4、ReentrantLock的四种获取锁方法对比

    /**
*获取一个锁
*三种情况:
*1、如果当下这个锁没有被任何线程(包括当前线程)持有,则立即获取锁,锁数量==1,之后再执行相应的业务逻辑
*2、如果当前线程正在持有这个锁,那么锁数量+1,之后再执行相应的业务逻辑
*3、如果当下锁被另一个线程所持有,则当前线程处于休眠状态,直到获得锁之后,当前线程被唤醒,锁数量==1,再执行相应的业务逻辑
* 简言之,获取锁,如果锁无法获取,当前线程被阻塞,直到锁可以获取并获取成功为止。
*/
public void lock() {
sync.lock();//调用NonfairSync(非公平锁)或FairSync(公平锁)的lock()方法
} /**
* lockInterruptibly():
* 1、 在当前线程没有被中断的情况下获取锁。
* 2、如果获取成功,方法结束。
* 3、如果锁无法获取,当前线程被阻塞,直到下面情况发生:
* 1)当前线程(被唤醒后)成功获取锁
* 2)当前线程被其他线程中断
*/
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
} /**
* 四点注意:
* 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));
}

第七章 ReentrantLock总结的更多相关文章

  1. 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...

  2. 《Entity Framework 6 Recipes》中文翻译系列 (38) ------ 第七章 使用对象服务之动态创建连接字符串和从数据库读取模型

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第七章 使用对象服务 本章篇幅适中,对真实应用中的常见问题提供了切实可行的解决方案. ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7  标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...

  4. Java语言程序设计(基础篇) 第七章 一维数组

    第七章 一维数组 7.2 数组的基础知识 1.一旦数组被创建,它的大小是固定的.使用一个数组引用变量,通过下标来访问数组中的元素. 2.数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储 ...

  5. objective-c第七章课后练习2

    题:改变第七章例子中print方法,增加bool参数,判断如果是YES则对分数进行约简 @interface Fraction : NSObject { //int num,den; } @prope ...

  6. 读《编写可维护的JavaScript》第七章总结

      第七章 事件处理 7.1 典型用法 作者首先给了个我们一个处理事件的方法.看起来也没啥俩样,不过后来给出的优化方法很值得学习: // 不好的写法 function handleClick(even ...

  7. 第七章 LED将为我们闪烁:控制发光二极管

     第七章 LED将为我们闪烁:控制发光二极管 本章我们将会看到一个完整的linux驱动程序,通过linux驱动程序控制LED的四个小灯,通俗的说就是通过向linux驱动程序来控制LED小灯的开关.用到 ...

  8. Getting Started With Hazelcast 读书笔记(第七章)

    第七章 部署策略 Hazelcast具有适应性,能根据不同的架构和应用进行特定的部署配置,每个应用可以根据具体情况选择最优的配置: 数据与应用紧密结合的模式(重点,of就是这种) 胖客户端模式(最好用 ...

  9. apue第七章学习总结

    apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...

随机推荐

  1. URL传入带有%的参数的解决方法

    在参数中含有%时,需要将其转义为它的编码格式%25 ,后面跟对应字符的ASCII(16进制)码值 如我想要传入参数mm=75%到后台,就需要对%进行编码为%25,所以实际输入的参数是mm=75%25 ...

  2. MQ java 基础编程

    MQ java 基础编程 编写人:邬文俊 编写时间 : 2006-2-16 联系邮件 : wenjunwu430@gmail.com 前言 通过 2 个多星期对 MQ 学习,在 partner 丁 & ...

  3. linux下每次git clone不需输入账号密码的方法

    在~/下, touch创建文件 .git-credentials, 用vim编辑此文件,输入内容格式: ame@zhenyun ~ $touch .git-credentials ame@zhenyu ...

  4. jQuery 用$.param(json) 将 Json 转换为 Url queryString

    如: var params = { param1: 'bar', param2: 'foo' }; var queryString = $.param(params); // queryString ...

  5. Phantomjs 生成多页PDF

    开篇 最近使用 Phantomjs 生成PDF,其中遇到一些问题,导致PDF生成失败,如出现空白文件或一页数据量太大,都是由于没有设置好格式导致.特别是分页问题,感觉资料很少,除了在 StackOve ...

  6. 【Mac】使用QuickTime Player录制屏幕录像

    我门分享都需要用到录屏软件,Mac系统有自带的QuickTime Player软件可以录制屏幕录像 环境与工具 1.mac系统 2.mac自带的QuickTime Player软件 使用方法 1.打开 ...

  7. 2018.07.27 bzoj4695: 最假女选手(线段树)

    传送门 线段树好题 支持区间加,区间取min" role="presentation" style="position: relative;"> ...

  8. 2018.07.22 codeforces750E(线段树维护状态转移)

    传送门 给出一个数字字串,给出若干个询问,询问在字串的一段区间保证出现2017" role="presentation" style="position: re ...

  9. String、StringBuffer与StringBuilder之间区别(转)

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...

  10. Scrapy爬取美女图片第三集 代理ip(上) (原创)

    首先说一声,让大家久等了.本来打算那天进行更新的,可是一细想,也只有我这样的单身狗还在做科研,大家可能没心思看更新的文章,所以就拖到了今天.不过忙了521,522这一天半,我把数据库也添加进来了,修复 ...