《并发编程》--10.重入锁
来源:互联网 发布:mysql 最小id 查询 编辑:程序博客网 时间:2024/05/21 10:11
在jdk5的时代,重入锁可以完全替代synchronized。但从jdk6开始对synchronized做了大量的优化,使两者在性能上差距不大。
以下是冲入锁的一段简单代码
public class ReenterLock implements Runnable {public static ReentrantLock lock = new ReentrantLock();public static int i = 0;@Overridepublic 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方法
@Overridepublic 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;}@Overridepublic 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();@Overridepublic 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():释放锁
阅读全文
0 0
- 《并发编程》--10.重入锁
- Java并发编程之重入锁
- Java并发编程之重入锁
- 并发编程--并发集合
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 并发编程
- 百度外卖wifi小票打印机如何设置连接手机
- pipework给docker设置ip
- 浏览器CSS兼容问题汇总及解决
- 前端之webpack
- 如何从零开始搭建高性能直播平台?
- 《并发编程》--10.重入锁
- Qt在Windows下的三种编程环境搭建
- 第4讲项目-将摄氏温度值转换为华氏温度值
- 封装Hibernate工具类
- shell下合并多文件内容
- [PHP]将二维数组中的键值替换为其中的某个下标的值,
- BZOJ3594: [Scoi2014]方伯伯的玉米田
- hdu 1532 最基础的求网络最大流问题
- pc端对应跳转手机端代码,适用所有网站!