《并发编程》--10.重入锁
2017-08-29 14:45
204 查看
在jdk5的时代,重入锁可以完全替代synchronized。但从jdk6开始对synchronized做了大量的优化,使两者在性能上差距不大。
以下是冲入锁的一段简单代码
从代码中可以看出:和synchronized相比,重入锁有着明显的操作过程,研发人员必须手动操作,合适加锁,合适释放锁。冲入锁对逻辑控制灵活性远远高于synchronized。
但是有一点必须注意:退出时必须释放锁,否则其他线程将无法继续访问临界区。,
重入锁对单线程是可以反复进入的,并不支持多线程,如下 例子,只修改run方法
同一线程在第二次获得锁时,将会和自己产生死锁。反之,释放锁的次数少了,那么相当于其他线程继续持有这个锁,其他线程将无法进入临界区。
1.中断响应
对于synchronized来说,如果一个线程在等待所,只有两个情况,要么持有锁继续执行,要不在持续等待中。
而对于重入锁来说:还多了另一种选择,等等待过程中,取消锁的等待。这种情况对于处理死锁有一定帮助。代码如下
2.锁申请等待限时
tryLock()方法接受两个参数,第1个表示等待时长,第二个表示计量单位。
表示在等这个锁的请求中,最多等待2秒,如果超过2秒没有获得锁,将返回false。代码如下
ReentrantLock的重要方法整理
1.lock():获得锁,如果所已经被占用,等待
2.lock.lockInterruptibly( );:获得所,有限响应中断
3.tryLock():尝试获得所,成功返回true,失败返回false。该方法不等待
4.lock.tryLock(5,TimeUnit.SECONDS):在指定时间获得所
5.unlock():释放锁
以下是冲入锁的一段简单代码
public class ReenterLock implements Runnable { public static ReentrantLock lock = new ReentrantLock(); public static int i = 0; @Override public void run() { for(int j = 0;j<1000000;j++){ lock.lock(); //加锁 try { i++; }finally{ lock.unlock(); //释放锁 } } } public static void main(String[] args) throws InterruptedException { ReenterLock ti = new ReenterLock(); Thread t1 = new Thread(ti); Thread t2 = new Thread(ti); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
从代码中可以看出:和synchronized相比,重入锁有着明显的操作过程,研发人员必须手动操作,合适加锁,合适释放锁。冲入锁对逻辑控制灵活性远远高于synchronized。
但是有一点必须注意:退出时必须释放锁,否则其他线程将无法继续访问临界区。,
重入锁对单线程是可以反复进入的,并不支持多线程,如下 例子,只修改run方法
@Override public void run() { for(int j = 0;j<1000000;j++){ lock.lock(); //加锁 lock.lock(); //加锁 try { i++; }finally{ lock.unlock(); //释放锁 lock.unlock(); //释放锁 } } }
同一线程在第二次获得锁时,将会和自己产生死锁。反之,释放锁的次数少了,那么相当于其他线程继续持有这个锁,其他线程将无法进入临界区。
1.中断响应
对于synchronized来说,如果一个线程在等待所,只有两个情况,要么持有锁继续执行,要不在持续等待中。
而对于重入锁来说:还多了另一种选择,等等待过程中,取消锁的等待。这种情况对于处理死锁有一定帮助。代码如下
public class IntLock implements Runnable{ public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock ; /** * 控制加锁顺序,方便构成死锁 */ public IntLock(int lock){ this.lock = lock; } @Override public void run() { try { if(lock ==1){ lock1.lockInterruptibly(); try { Thread.sleep(500); } catch (InterruptedException e) { lock2.lockInterruptibly(); } } else{ lock2.lockInterruptibly(); try { Thread.sleep(500); } catch (InterruptedException e) { lock1.lockInterruptibly(); } } } catch (InterruptedException e) { e.printStackTrace(); }finally { if(lock1.isHeldByCurrentThread());{ lock1.unlock(); } if(lock2.isHeldByCurrentThread());{ lock2.unlock(); } System.out.println(Thread.currentThread().getId()+" : 线程退出 "); } } public static void main(String[] args)throws InterruptedException{ IntLock i1 = new IntLock(1); IntLock i2 = new IntLock(2); Thread t1 = new Thread(i1); Thread t2 = new Thread(i2); t1.start();t2.start(); Thread.sleep(1000); t2.interrupt();//中断其中一个线程 } }
2.锁申请等待限时
tryLock()方法接受两个参数,第1个表示等待时长,第二个表示计量单位。
表示在等这个锁的请求中,最多等待2秒,如果超过2秒没有获得锁,将返回false。代码如下
public class TimeLock implements Runnable{ public static ReentrantLock lock = new ReentrantLock(); @Override public void run() { try{ if(lock.tryLock(5,TimeUnit.SECONDS)){//第一个表示等待时长,第二个表示计量单位 Thread.sleep(6000); }else{ System.out.println("获得所失败!!!"); } }catch(InterruptedException e){ e.printStackTrace(); }finally { if (lock.isHeldByCurrentThread()) lock.unlock(); } } public static void main(String[] args)throws InterruptedException{ TimeLock i1 = new TimeLock(); Thread t1 = new Thread(i1); Thread t2 = new Thread(i1); t1.start();t2.start(); } }
ReentrantLock的重要方法整理
1.lock():获得锁,如果所已经被占用,等待
2.lock.lockInterruptibly( );:获得所,有限响应中断
3.tryLock():尝试获得所,成功返回true,失败返回false。该方法不等待
4.lock.tryLock(5,TimeUnit.SECONDS):在指定时间获得所
5.unlock():释放锁
相关文章推荐
- 《深入理解java虚拟机》学习笔记10——并发编程(二)
- 《深入理解java虚拟机》学习笔记10——并发编程(二)
- (转)《深入理解java虚拟机》学习笔记10——并发编程(二)
- 16进制字符串转换成10进制数或把10进制数转换成16进制字符串
- NHibernate Step By Step(10)-常用的配置属性
- 第13周项目10-递归法求两个数的最大公约数
- 如何获取Input标签自定义属性的值ie 8 9 10下取值
- 学习MySQL的一些记录笔记(1)10-28
- UVa #11582 Colossal Fibonacci Numbers! (例题10-1)
- 深度学习与计算机视觉系列(10)_细说卷积神经网络
- Castle ActiveRecord学习实践(10):深度分析Schema Pitfals
- 10 06 07 没进步
- Arcgis server 10服务无法启动
- MIT的《深度学习》精读(10)
- Linux应用编程基础--(10)进程间通信system V
- JNI由浅入深_10_JNI 综合开发
- Entity Framework 6 Recipes 2nd Edition(10-10)译 - > 为TPH继承的插入、更新、删除操作映射到存储过程
- TCP/IP详解学习笔记(10)-TCP连接的建立与中止
- 10 06 25 又是2点
- C#高效编程话题集3(每期10话题)