热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

同步控制之“重入锁”

2019独角兽企业重金招聘Python工程师标准我们首先将介绍synchronized、Object.wait()和Object.notify()方法的替代品(

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    我们首先将介绍synchronized、Object.wait()和Object.notify()方法的替代品(或者说是增强版) ——重入锁。

一、synchronized的功能扩展:重入锁

    重入锁可以完全替代synchronized关键字。在JDK5.0的早期版本中,重入锁的性能远远好于synchronized,但从JDK6.0开始,JDK在synchronized上做了大量的优化,是的两者的性能差距并不大。重入锁使用java.util.concurrent.locks.ReentrantLock类来实现。下面是一段最简单的重入锁使用案例:

import java.util.concurrent.locks.ReentrantLock;public class Thread2 implements Runnable{public static ReentrantLock lock &#61; new ReentrantLock();public static int i&#61;0;&#64;Overridepublic void run() {for (int j &#61; 0; j <1000000; j&#43;&#43;) {lock.lock();try {i&#43;&#43;;}finally {lock.unlock();}}}public static void main(String[] args) throws InterruptedException {Thread2 rl &#61; new Thread2();//类名Thread t1 &#61; new Thread(rl);Thread t2 &#61; new Thread(rl);t1.start();t2.start();//启动子线程t1、t2t1.join();t2.join();//结束子线程t1、t2System.out.println(i);}
}

    根据以上代码&#xff0c;使用重入锁保护临界区资源i&#xff0c;确保多线程对i操作的安全性。从这段代码可以看到&#xff0c;与synchronized相比&#xff0c;重入锁有着显示的操作过程。开发人员必须手动何时枷锁&#xff0c;何时释放锁。也正因为这样&#xff0c;重入锁对逻辑控制的灵活性要远远好于synchronized&#xff0c;但值得注意的是&#xff0c;在退出临界区时&#xff0c;必须记得释放&#xff0c;否则&#xff0c;其它线程就没有机会再访问临界区了。

for (int j &#61; 0; j <1000000; j&#43;&#43;) {lock.lock();lock.lock();try {i&#43;&#43;;}finally {lock.unlock();lock.unlock();}
}

    一个线程连续两次获得同一把锁。这是允许的&#xff01;如果不允许这么操作&#xff0c;那么同一个线程在第2次获得锁时&#xff0c;将会和自己产生死锁。程序就会“卡死”在第2次申请锁的过程中。需要注意的是&#xff0c;如果同一个线程多次获得锁&#xff0c;那么在释放锁的时候&#xff0c;也必须释放相同次数。

  • 释放锁的次数多了&#xff1a;会得到一个java.lang.IllegalMonitorStateException异常。
  • 释放锁的次数少了&#xff1a;相当于线程还持有这个锁&#xff0c;因此其它线程也无法进入临界区。

 


转载于:https://my.oschina.net/Clarences/blog/1547677


推荐阅读
author-avatar
阿尔及利亚奥兰叉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有