Java ReEntrantLock (Java代码实战-001)
Lock类也可以实现线程同步,而Lock获得锁需要执行lock方法,释放锁需要执行unLock方法
Lock类可以创建Condition对象,Condition对象用来使线程等待和唤醒线程,需要注意的是Condition对象的唤醒的是用同一个Condition执行await方法的线程,所以也就可以实现唤醒指定类的线程
Lock类分公平锁和不公平锁,公平锁是按照加锁顺序来的,非公平锁是不按顺序的,也就是说先执行lock方法的锁不一定先获得锁 Lock类有读锁和写锁,读读共享,写写互斥,读写互斥
import java.sql.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; /**
* ReEntrantLockTest
*/
public class ReEntrantLockTest {
private static final int THREAD_COUNT = 4;
private static final int WAIT_TIMES = 5; public static void main(String[] args) {
// 默认是非公平锁
final ReentrantLock lock = new ReentrantLock(); final Condition con = lock.newCondition();
final Runnable add = new Runnable() {
@Override
public void run() {
System.out.println("Time: " + new java.util.Date() + " Pre " + lock);
// 获取到锁的话立即返回,否则一直处于等待状态
lock.lock();
try {
// 使当前线程处于等待状态,直到被信号通知或中断,此线程处于等待状态,其它线程也可以获取锁
con.await(WAIT_TIMES, TimeUnit.SECONDS); // seleep状态时则不会释放锁
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Time:" + new java.util.Date() + " Post " + lock);
lock.unlock();
}
}
}; final ExecutorService exec = Executors.newFixedThreadPool(THREAD_COUNT);
for (int i = 0; i < THREAD_COUNT; i++) {
exec.submit(add);
}
exec.shutdown();
}
}
ReenTrantLock可重入锁(和synchronized的区别)总结
可重入性:
从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入的,两者关于这个的区别不大。两者都是同一个线程没进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。
锁的实现:
Synchronized是依赖于JVM实现的,而ReenTrantLock是JDK实现的,有什么区别,说白了就类似于操作系统来控制实现和用户自己敲代码实现的区别。前者的实现是比较难见到的,后者有直接的源码可供阅读。
性能的区别:
在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReenTrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。
功能区别:
便利性:很明显Synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。
锁的细粒度和灵活度:很明显ReenTrantLock优于Synchronized
ReenTrantLock独有的能力:
1. ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。
2. ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。
3. ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。
ReenTrantLock实现的原理:
在网上看到相关的源码分析,本来这块应该是本文的核心,但是感觉比较复杂就不一一详解了,简单来说,ReenTrantLock的实现是一种自旋锁,通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。
什么情况下使用ReenTrantLock:
答案是,如果你需要实现ReenTrantLock的三个独有功能时。
Java ReEntrantLock (Java代码实战-001)的更多相关文章
- 通俗易懂详解Java代理及代码实战
一.概述 代理模式是Java常用的设计模式之一,实现代理模式要求代理类和委托类(被代理的类)具有相同的方法(提供相同的服务),代理类对象自身并不实现真正的核心逻辑,而是通过调用委托类对象的相关方法来处 ...
- Java秒杀系统实战系列~商品秒杀代码实战
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即“商品秒杀”功能模块的代码实战. 内容: “商品秒杀”功能模块是建立在“商品详情”功 ...
- [Java聊天室server]实战之二 监听类
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
- [Java聊天室server]实战之五 读写循环(服务端)
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
- java设计模式综合项目实战视频教程
java设计模式综合项目实战视频教程 视频课程目录如下: 第01节课:本课程整体内容介绍:X-gen系统概况,包括:引入.X-gen项目背景.X-gen的HelloWorld第02节课:X-gen整体 ...
- Java ReentrantLock和synchronized两种锁定机制的对比
多线程和并发性并不是什么新内容,但是 Java 语言设计中的创新之一就是,它是第一个直接把跨平台线程模型和正规的内存模型集成到语言中的主流语言.核心类库包含一个 Thread 类,可以用它来构建.启动 ...
- [Java聊天室server]实战之三 接收循环
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识.但学习之前,更 ...
- Java性能调优实战,覆盖80%以上调优场景
Java 性能调优对于每一个奋战在开发一线的技术人来说,随着系统访问量的增加.代码的臃肿,各种性能问题便会层出不穷. 日渐复杂的系统,错综复杂的性能调优,都对Java工程师的技术广度和技术深度提出了更 ...
- 轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)
轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)(国家级奖项获奖作品升级版,四版累计印刷27次发行量超10万册的轻量级Jav ...
随机推荐
- Win8 Metro风格的Web桌面HteOS
前言 曾经天天折腾ExtJS,折腾累了.近期这段时间開始用jquery来做一些东西,发现还是蛮有意思的.可是做到最后才发现,原来做好设计真的很重要. 上图就是HteOS项目的截图,眼下正在开发 ...
- 使用Camera进行拍照 & 后台静默拍照的思路
Android中的Camera可以用来进行自定义相机.取景框实时预览.拍照等操作.在5.0中,这个类不推荐使用了,新出了一个Camera2,那个东西没怎么研究过,反正一时半会用不到.本篇讲解的是如果用 ...
- Eclipse断点调试(DBG)Android应用
1.添加断点 双击左侧边框便可添加断点,右击也能添加断点. 2.进入调试模式 点击虫子,然后选择工程运行,快捷键为单击F11 ,如果是正常运行就是Ctrl+F11 3.单步调试+跳到下一个断点 运行到 ...
- 分享一个Panda C-60 维修心得
昨天丰臣国际搞了个汽车后备箱市场,说白了就是一帮闲的没事儿的"白领"大热天把自家闲置的东西拿过来练练摊,这个形式还是不错的,中间看到了一个熊猫的CD机,一眼就看上了,虽说CD早就过 ...
- verilog语法实例学习(7)
常用的时序电路介绍 组合电路:这类电路的输出信号值仅却决于输入端信号值. 时序电路:时序电路的输出值不仅取决于当前的输入值,还取决于电路的历史状态,所以时序逻辑电路中包含保存逻辑信号值的存储元件,存储 ...
- json schema校验
工作中使用到了json schema格式校验的问题,在网上查了些资料,结合自己的理解记录一下. json schema可以对json结果字符串做出一些约束,例如: 1. 值类型是:array, obj ...
- “秘书九段的故事”,要学会给自己制定一个工作N段或者技术N段
总经理要求秘书安排次日上午九点开一个会议.在这件事下,什么是任务?什么是结果? 通知到所有参会的人员,然后秘书自己也参加会议来做服务,这是“任务”.但我们想要的结果是什么呢?下面是一至九段秘书的不同做 ...
- Binary Tree Maximum Path Sum leetcode java
题目: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tr ...
- centos 下 mysql+keepalived实现双主自由切换
目录 ip规划 mysql双主配置 keepalived配置 mysql1中keepalived的配置 mysql2中keepalived的配置 VIP漂移检测 本文的目的是搭建一个互为主从的mysq ...
- 解决使用Properties读取中文乱码问题
web服务返回的是多行以key和value对应的键值对,且编码为utf-8.我的项目使用的编码也是utf-8,但是我用Properties读取中文的时候,打印出来的总是乱码. 后来网上查了一下,得到如 ...