常用方式:

        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. js Array Map and Set

    Array slice slice()就是对应String的substring()版本,它截取Array的部分元素,然后返回一个新的Array: var arr = ['A', 'B', 'C', ' ...

  2. js 判断字符串是否包含某字符串,String对象中查找子字符,indexOf

    var Cts = "bblText";   if(Cts.indexOf("Text") > 0 ) {     alert('Cts中包含Text字符 ...

  3. Java 的CardPanel用法

    Java code? 1 2 3 4 5 6               card = new CardLayout(5,5);//5,5是组件间隔                pane = new ...

  4. Laravel 5 如何对部份 URI 禁用 CSRF 验证

    打开中间件 VerifyCsrfToken.php 在其 $except 属性中添加要禁用的 uri,如: api/user/add api/user/* api/*

  5. Java中通过SimpleDateFormat格式化当前时间:/** 输出格式:20060101010101001**/

    import java.util.*; import java.text.SimpleDateFormat; int y,m,d,h,mi,s,ms; String cur; Calendar cal ...

  6. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  7. Bootstrap验证

    <div class="modal fade" id="myModal" tabindex="-1" role="dialo ...

  8. zeromq学习记录(二)天气更新服务器使用ZMQ_SUB ZMQ_PUB

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  9. 【Win】编写简单的bat文件

    bat是dos下的批处理文件.批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd. ...

  10. Realtek 8192cu 支持 Android Hotspot 软ap

    http://www.cnblogs.com/bpasser/archive/2011/10/15/2213483.html Android 2.2 开始增加了WiFi Hotspot,可将Andro ...