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 ...
随机推荐
- 零基础学python-2.17 文件、open()、file()
今天我们来说说文件,以及跟文件有关的内建函数open和file 首先我们在python的根文件夹下建一个名为"123"的txt文本文件 文件中面我们输入一些文本 watermark ...
- machine learning in coding(python):使用贪心搜索【进行特征选择】
print "Performing greedy feature selection..." score_hist = [] N = 10 good_features = set( ...
- mount -o remount,rw /
init=/bin/sh mount -o remount,rw /; sed -i 's/指定字符串/&希望插入的字符串/' 文件 在一文件中指定的字符后插入内容 sed -i 's/指定的 ...
- 3-4 第三天 Generator生成器
Generator是ES6里面的新增规范,ES6其实就是ES2015.ES5.ES6.ES7这些术语大家上网一查就都明白了.JavaScript是一个范程,就是我们说的JS.ES就是ECMA Scri ...
- 试用php的ping命令
使用PHP自动PING IP,校检网络连接是否正常! <?php $server = 'ping kalvin.cn -n 1'; $last_line = exec($server, $arr ...
- HDU2186
2019-05-30 19:31:10 水题 #include <bits/stdc++.h> using namespace std; int main() { int c; scanf ...
- 2-SAT的小总结(POJ 3683 POJ 3207)
记住几个最重要的公式: xANDy=0<=>(x=>y′)AND(y=>x′) xANDy=1<=>(x′=>x)AND(y′=>y) xORy=0&l ...
- hdu 4297
有两个基础需要掌握: RMQ,以及LCA. RMQ:dp[i][j]表示下标从i开始,长度为2^j的一段元素中的最值.则易得状态转移如下:dp[i][j]=max/min(dp[i][j-1],dp[ ...
- php中curl的详细解说 【转载】
这几天在帮一些同学处理问题的时候,突然发现这些同学是使用file_get_contents()函数来采集页面内容的,貌似都没有curl的概念亦或是对这种工具特别不敏感, 本文我来给大家详细介绍下cUR ...
- Spring Boot (17) 发送邮件
添加依赖 <!--发送邮件 --> <dependency> <groupId>org.springframework.boot</groupId> & ...