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 ...
随机推荐
- Androlid入门之文件系统操作(三)文件读写
import java.io.*; import android.app.Activity; import android.os.Bundle; import android.view.Vi ...
- 【BZOJ 1572】 工作安排
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1572 [算法] 贪心 先将这些工作按截至时间排序 建立一个小根堆,当决策是否完成一项 ...
- 三个命令解决ASTGO服务器重启后各种问题
SSH 命令方式登录到服务器,依次执行下面三个命令. service httpd restart service mysqld restart safe_asterisk 前面两个命令提示无效,尝试从 ...
- 跟渣渣辉玩ffms
[SQL] /* Navicat MySQL Data Transfer Source Server : root Source Server Version : 50717 Source Host ...
- Oracle配置说明
当Oracle安装完成后,为后续能够顺利得导出空表,特做一下配置(重点关注2.1) 1.1.查询空表select table_name from user_tables where NUM_ROWS= ...
- Android开发笔记(11)——DialogFragment & 点击监听
转载请注明:http://www.cnblogs.com/igoslly/p/6931519.html DialogFragment使用 & 点击监听 /* DialogFragment是用于 ...
- Assembly之instruction之Indirect Autoincrement Mode
Assembler Code Content of ROMMOV @R10+,0(R11) MOV @R10+,0(R11) Length: One or two words Operation: ...
- HTML基础知识总结(一)
概述 HTML是将内容和内容显示形式结合在一起的语言,它对于内容显示形式的控制,主要是通过标签(元素)的属性,由于它对“内容显示形式”存在着很多的弊端,所以之后就出现了CSS,CSS就相当 ...
- 【C++】四种排序算法的时间比较
四种排序算法的时间比较 [注]clock函数对输入(用户输入)元素N排序的计时 #include<iostream> #include<time.h> using namesp ...
- IronPython中共享的C#基类如何向下转型
在项目中,我们使用IronPython来定义工作流脚本来以应对科研多变的需求.项目使用的主要语言仍然是C#,使用C#封装了各种基础服务与基础设施.Python脚本只使用C#提供的服务,或者说只定义了逻 ...