ReentrantLock(排他锁)
在多线程操作时。保证一块共享资源的原子性。第一想到的就是用synchronized关键字
在jdk5提供一个更灵活更强大的 ReentrantLock
使用reentrantLock.lock();获得锁 使用reentrantLock.unlock();释放锁
public class ReentrantLockTest {
ReentrantLock reentrantLock = new ReentrantLock();
public void add(Object data) throws InterruptedException {
try {
reentrantLock.lock();
System.out.println("模拟新增耗时");
Thread.sleep(2000);
System.out.println("新增完毕");
} finally {
// TODO: handle finally clause
reentrantLock.unlock();
}
}
public void get() throws InterruptedException {
try {
reentrantLock.lock();
System.out.println("模拟获取");
Thread.sleep(1000);
System.out.println("新增完毕");
} finally {
// TODO: handle finally clause
reentrantLock.unlock();
}
}
public static void main(String[] args) {
final ReentrantLockTest reentrantLockTest=new ReentrantLockTest();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLockTest.add(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLockTest.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();;
}
synchronized与ReentrantLock区别
1.synchronized是交给jvm来调度的。ReentrantLock是通过java代码控制的
2.在synchronized在很多线程竞争的时候会使性能大大下降ReentrantLock在很多线程竞争是不会
3.ReentrantLock必须配合finally 否则容易产生死锁
ReentrantLock reentrantLock = new ReentrantLock();
public void Test1() {
reentrantLock.lock();
/*
* 执行逻辑
*/
Test2();
}
public void Test2() {
reentrantLock.unlock();
}
5.ReentrantLock可以进行公平锁选择
什么情况下选用ReentrantLock
1.某个线程在等待一个锁的控制权的这段时间需要中断 tryLock
public class ReentrantLockTest {
ReentrantLock reentrantLock = new ReentrantLock();
public void add(Object data) throws InterruptedException {
try {
reentrantLock.lock();
Thread.sleep(10000);
System.out.println("模拟新增耗时");
} finally {
// TODO: handle finally clause
reentrantLock.unlock();
}
}
public void get() throws InterruptedException {
try {
reentrantLock.tryLock(1000, TimeUnit.MILLISECONDS);//尝试获得锁1000毫秒 获取不到放弃
System.out.println("模拟获取");
Thread.sleep(1000);
System.out.println("获取完毕");
} finally {
// TODO: handle finally clause
reentrantLock.unlock();
}
}
public static void main(String[] args) {
final ReentrantLockTest reentrantLockTest=new ReentrantLockTest();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLockTest.add(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLockTest.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("执行其他业务逻辑");
}
},"t2").start();;
}
}
第一个线程获取锁 等待5秒。当reentrantLock.tryLock(1000, TimeUnit.MILLISECONDS) 会尝试获得锁 若果1秒之内没获取 抛出异常 继续往下执行
打印
模拟获取
获取完毕Exception in thread "t2"
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
at java.util.concurrent.locks.ReentrantLock.unlock(Unknown Source)
at com.bjsxt.height.concurrent019.ReentrantLockTest.get(ReentrantLockTest.java:32)
at com.bjsxt.height.concurrent019.ReentrantLockTest$2.run(ReentrantLockTest.java:56)
at java.lang.Thread.run(Unknown Source)
模拟新增耗时
2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
public static void main(String[] args) throws InterruptedException {
final ReentrantLock reentrantLock = new ReentrantLock();
final Condition condition1= reentrantLock.newCondition();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLock.lock();
condition1.await();
System.out.println("线程1往下执行");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
reentrantLock.lock();
Thread.sleep(5000);
condition1.signal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
},"t2").start();
Thread.sleep(2000);
//取消 condition1等待
}
reentrantLock.newCondition()可以new多个 。可以通过reentrantLock.signalAll()唤醒所有等待的condition
3.具有公平锁功能,每个到来的线程都将排队等候
ReentrantLock reentrantLock = new ReentrantLock(true) 则为公平所
ReentrantLock(排他锁)的更多相关文章
- 可重入排他锁ReentrantLock源码浅析
1.引子 "ReentrantLock"单词中的“Reentrant”就是“重入”的意思,正如其名,ReentrantLock是一个支持重入的排他锁,即同一个线程中可以多次获得同步 ...
- 并发和多线程(九)--AbstractQueuedSynchronizer排他锁基本原理
AbstractQueuedSynchronizer简称为AQS,AQS是ReentrantLock.CountdownLatch.CycliBarrier等并发工具的原理/基础,所以了解AQS的原理 ...
- 关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析
关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析 如下代码,当我们在使用 ReentrantLock 进行加锁和解锁时,底层到底是如何帮助我们进行控制的啦 ...
- php lock_sh共享锁 与 lock_ex排他锁
参考网站:http://hi.baidu.com/honly1215/item/8d27a66d11689c3aac3e83fe 文件锁有两种:共享锁和排他锁,也就是读锁(LOCK_SH)和写锁(LO ...
- [数据库事务与锁]详解六: MySQL中的共享锁与排他锁
注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大 ...
- 共享锁【S锁】 排他锁【X锁】
排它锁又称为写锁((eXclusive lock,简记为X锁)),若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁.它防止任何其它事务获 ...
- mysql共享锁与排他锁
mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...
- Mysql的排他锁和共享锁
今天看代码看到有select name from user where id = 1 for update,有点懵逼,完全没有见过,只能说自己见识少了,那就只能学习一下.先做一下基本知识了解(大部分都 ...
- 获取数据库时间sql 以及行级锁总结-共享锁-排他锁-死锁
--TRUNC(date,[fmt]) /TRUNC(number[,decimals])SELECT SYSDATE FROM dual;SELECT TRUNC(SYSDATE) FROM dua ...
随机推荐
- 抽象类(Abstract)和接口的不同点、共同点(Interface)。
同样点: (1) 都能够被继承 (2) 都不能被实例化 (3) 都能够包括方法声明 (4) 派生类必须实现未实现的方法 区 别: (1) 抽象基类能够定义字段.属性.方法实现.接口仅仅能定义属性.索引 ...
- luogu2154 [SDOI2009] 虔诚的墓主人 离散化 树状数组 扫描线
题目大意 公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.一块墓地的虔诚度是指以这块墓地为中心的十字架的数目,一个十字架可以看成中间是墓地,墓地的正上.正 ...
- oc60--Category 分类 练习
// main.m // Category练习 #import <Foundation/Foundation.h> #import "NSString+NJ.h" // ...
- hdoj-1896 stones
Stones Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Sub ...
- js中 if不判断解决方式
$(function() { $("#number").blur(function() { var number = $('#number').val(); var num = $ ...
- [转] 理解 Dubbo SPI 扩展机制
写在前面 最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题.从 2016 年左右开始接触到 dub ...
- 题解报告:hdu 4764 Stone(巴什博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 Problem Description Tang and Jiang are good frie ...
- intellij 创建java web项目(maven管理的SSH)
intellij 创建java web项目(maven管理的SSH) 环境intellij IDEA14.MAVEN.Spring.Struts2.Hibernate.Java Web.工程搭建. 1 ...
- 用DIV遮罩解决checkbox勾选无效的问题
在前端开发的过程中,遇到一种情况,需要勾选,为了用户的操作便捷就将click事件放到了DIV上.(其中使用了knockout.js) 代码大概如下: <div id="one" ...
- DNN结构演进History—CNN-GoogLeNet :Going Deeper with Convolutions
抄袭了一片文章,进行少量修改:http://www.gageet.com/2014/09203.php 作者:Christian Szegedy( google ) 刘伟(北卡罗来纳 ...