在多线程操作时。保证一块共享资源的原子性。第一想到的就是用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(排他锁)的更多相关文章

  1. 可重入排他锁ReentrantLock源码浅析

    1.引子 "ReentrantLock"单词中的“Reentrant”就是“重入”的意思,正如其名,ReentrantLock是一个支持重入的排他锁,即同一个线程中可以多次获得同步 ...

  2. 并发和多线程(九)--AbstractQueuedSynchronizer排他锁基本原理

    AbstractQueuedSynchronizer简称为AQS,AQS是ReentrantLock.CountdownLatch.CycliBarrier等并发工具的原理/基础,所以了解AQS的原理 ...

  3. 关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析

    关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析 如下代码,当我们在使用 ReentrantLock 进行加锁和解锁时,底层到底是如何帮助我们进行控制的啦 ...

  4. php lock_sh共享锁 与 lock_ex排他锁

    参考网站:http://hi.baidu.com/honly1215/item/8d27a66d11689c3aac3e83fe 文件锁有两种:共享锁和排他锁,也就是读锁(LOCK_SH)和写锁(LO ...

  5. [数据库事务与锁]详解六: MySQL中的共享锁与排他锁

    注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大 ...

  6. 共享锁【S锁】 排他锁【X锁】

    排它锁又称为写锁((eXclusive lock,简记为X锁)),若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁.它防止任何其它事务获 ...

  7. mysql共享锁与排他锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  8. Mysql的排他锁和共享锁

    今天看代码看到有select name from user where id = 1 for update,有点懵逼,完全没有见过,只能说自己见识少了,那就只能学习一下.先做一下基本知识了解(大部分都 ...

  9. 获取数据库时间sql 以及行级锁总结-共享锁-排他锁-死锁

    --TRUNC(date,[fmt]) /TRUNC(number[,decimals])SELECT SYSDATE FROM dual;SELECT TRUNC(SYSDATE) FROM dua ...

随机推荐

  1. 一条SQL面试题

    求其中同一个主叫号码的两次通话之间间隔大于10秒的通话记录ID 例如:6,7,8,9,10条记录均符合 ID 主叫号码 被叫号码      通话起始时间            通话结束时间       ...

  2. Autobiography

    Autobiography My name is Donggongdechen. I am ** years old. I was born in XuChang, HeNan province, t ...

  3. cocos creator制作微信小游戏

    2019-05-30 22:11:47 基础: javaScript基础   https://www.bilibili.com/video/av34087791?from=search&sei ...

  4. Your configuration specifies to merge with the ref 'refs/heads/v.autoCheckProduct.20190325' from the remote, but no such ref was fetched.

    问题: 创建新的分支,当我们执行git pull,出现如下错误 解决办法: 1.切换到主分支(或者被依赖的分支,也就是你从哪个分支上拉取新的分支),博主这里是master分支 2.执行以下两个命令 3 ...

  5. MSSQL:删除系统作业计划

    use [msdb]declare @job_name varchar(100)set @job_name = N'EveryDayBackup.Subplan_1'--注:jobName为维护计划对 ...

  6. 【LOJ#10115,tyvj1473】校门外的树(第3次升级)

    PS:思路来源于Clove_unique的博客,在此万分感谢 这道题可以用树状数组轻松过,然而...树状数组不太熟悉,还是用线段树比较好(虽然代码比较长) [思路分析] [一开始的思路] 最开始的错误 ...

  7. 【poj1995】快速幂

    题目大意 求a^b %p 1≤a,b,p≤10^9 思路 时间O(10^9)一定会爆T,采用数学方法+位运算,得到O(log b)的快速幂算法 代码 #include<cstdio> #i ...

  8. facade 模式和gateway模式的区别

    原文:http://stackoverflow.com/questions/4422211/what-is-the-difference-between-facade-and-gateway-desi ...

  9. PHP开发笔记(三)关于PHP伪静态的问题总结

    Apache 第一个问题就是关于PHPStudy集成Apache环境下5.5版本以上”No input file specified“问题. 针对TP5框架,以下是.htaccess文件的配置,PHP ...

  10. 关于AS使用git的那些奇葩事儿

    首先致谢: http://blog.csdn.net/a10615/article/details/52135617, 我们不生产代码, 我们只做大自然的搬运工! 总结 1. 首次无法push问题: ...