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 ...
随机推荐
- Mongodb---记一次事故故障
2014.06.19.001---故障报告 事故发生时间 事故简述 事故责任方 是否解决 19:21-20:15 IISserverD盘即将溢出 是 一.事故描写叙述: 在19:21收到警报.显示II ...
- Android shape自定义形状,设置渐变色
<?xml version="1.0" encoding="utf-8"?> <!-- android:shape=["rect ...
- ssdb底层实现——ssdb底层是leveldb,leveldb根本上是skiplist(例如为存储多个list items,必然有多个item key,而非暴力string cat),用它来做redis的list和set等,势必在数据结构和算法层面上有诸多不适
我已经在用ssdb的hash结构,存储了很多数据了,但是我现在的用法正确吗? 我使用hash结构合理吗? 1. ssdb数据库说是类似redis,而且他们都有hash结构,但是他们的命名有点不同,ss ...
- CodeForces - 811C Vladik and Memorable Trip(dp)
C. Vladik and Memorable Trip time limit per test 2 seconds memory limit per test 256 megabytes input ...
- B1231 [Usaco2008 Nov]mixup2 混乱的奶牛 状压dp
发现是状压dp,但是还是不会...之前都白学了,本蒟蒻怎么这么菜,怎么都学不会啊... 其实我位运算基础太差了,所以状压学的不好. 题干: Description 混乱的奶牛 [Don Piele, ...
- [SpringMVC]定义多个前缀映射的问题
转自:https://penciltim.iteye.com/blog/501073 我在web.xml里面定义多个dispatch-servlet的前缀映射,像下面这样 <!-- Servle ...
- 比较两个Json对象是否相等
一个前端同事遇到的面试题,抽空写了写,也算是个积累 1.先准备三个工具方法,用于判断是否是对象类型,是否是数组,获取对象长度 function isObj(object) { return objec ...
- Git 和 Redis 的基本认识
一: Git 二: Redis
- POJ 2945 trie树
Find the Clones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7704 Accepted: 2879 Descr ...
- CSS3 3D变换实例 滚动的正方体
笔记: 2D变换 transform 位移 translateX() translateY() 简写:translate(X值,Y值) 正值向右,负值向左 旋转 rotate() rotat ...