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

Lock

Lock是一个接口,提供了无条件的、可轮询的、定时的、可中断的锁获取操作,所有加锁和解锁的方法都是显式的。包路径是:java.util.concurrent.locks.Lock。核心方法有 lock()unlock()tryLock(),实现类有 ReentrantLockReentrantReadWriteLock.ReadLockReentrantReadWriteLock.WriteLock

** 方法及说明 **

public abstract interface Lock {// 获取锁。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,// 该线程将一直处于休眠状态void lock();// 如果当前线程未被中断,则获取锁。如果锁可用,则获取锁,并立即返回。// 如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:// 锁由当前线程获得;或者其他某个线程中断当前线程,并且支持对锁获取的中断。// 如果当前线程:在进入此方法时已经设置了该线程的中断状态;// 或者在获取锁时被中断,并且支持对锁获取的中断,则将抛出`InterruptedException`,并清除当前线程的已中断状态void lockInterruptibly() throws InterruptedException;// 仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值 true。// 如果锁不可用,则此方法将立即返回值 false。通常对于那些不是必须获取锁的操作可能有用boolean tryLock();// 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。// 如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,// 将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态boolean tryLock(long time, TimeUnit unit) throws InterruptedException;// 释放锁。对应于 lock()、tryLock()、tryLock(time, unit)、lockInterruptibly() 等操作,// 如果成功的话应该对应着一个`unlock()`,这样可以避免死锁或者资源浪费void unlock();// 返回用来与此 Lock 实例一起使用的 Condition 实例Condition newCondition();
}

ReentrantLock

ReentrantLock是Lock的实现类,是一个互斥的同步器,它具有扩展的能力。在竞争条件下,ReentrantLock 的实现要比现在的 synchronized 实现更具有可伸缩性。(有可能在 JVM 的将来版本中改进 synchronized 的竞争性能)这意味着当许多线程都竞争相同锁定时,使用 ReentrantLock 的吞吐量通常要比 synchronized 好。换句话说,当许多线程试图访问 ReentrantLock 保护的共享资源时,JVM 将花费较少的时间来调度线程,而用更多个时间执行线程。虽然 ReentrantLock 类有许多优点,但是与同步相比,它有一个主要缺点 — 它可能忘记释放锁定。ReentrantLock是在工作中对方法块加锁使用频率最高的。

** 使用方法如下: **

class X {private final ReentrantLock lock = new ReentrantLock();// …public void m() {lock.lock(); // 获得锁try {// … 方法体} finally {lock.unlock();//解锁}}
}

** Lock与synchronized 的比较: **

  1. Lock使用起来比较灵活,但是必须有释放锁的动作;
  2. Lock必须手动释放和开启锁,synchronized 不需要;
  3. Lock只适用与代码块锁,而synchronized 对象之间的互斥关系;

示例

请注意以下两种方式的区别:

第一种方式:两个方法之间的锁是独立的

public class ReentrantLockDemo {public static void main(String[] args) {final Count ct = new Count();for (int i = 0; i < 2; i++) {new Thread() {public void run() {ct.get();}}.start();}for (int i = 0; i < 2; i++) {new Thread() {public void run() {ct.put();}}.start();}}
}class Count {public void get() {final ReentrantLock lock = new ReentrantLock();try {lock.lock(); // 加锁System.out.println(Thread.currentThread().getName() + " get begin");Thread.sleep(1000);// 模仿干活System.out.println(Thread.currentThread().getName() + " get end");lock.unlock(); // 解锁} catch (InterruptedException e) {e.printStackTrace();}}public void put() {final ReentrantLock lock = new ReentrantLock();try {lock.lock(); // 加锁System.out.println(Thread.currentThread().getName() + " put begin");Thread.sleep(1000);// 模仿干活System.out.println(Thread.currentThread().getName() + " put end");lock.unlock(); // 解锁} catch (InterruptedException e) {e.printStackTrace();}}
}

运行结果如下(每次运行结果都是不一样的,仔细体会一下):

Thread-0 get begin
Thread-1 get begin
Thread-2 put begin
Thread-3 put begin
Thread-0 get end
Thread-2 put end
Thread-3 put end
Thread-1 get end

第二种方式,两个方法之间使用相同的锁

ReentrantLockDemo 类的内容不变,将Count中的ReentrantLock改成全局变量,如下所示:

class Count {final ReentrantLock lock = new ReentrantLock();public void get() {try {lock.lock(); // 加锁System.out.println(Thread.currentThread().getName() + " get begin");Thread.sleep(1000);// 模仿干活System.out.println(Thread.currentThread().getName() + " get end");lock.unlock(); // 解锁} catch (InterruptedException e) {e.printStackTrace();}}public void put() {try {lock.lock(); // 加锁System.out.println(Thread.currentThread().getName() + " put begin");Thread.sleep(1000);// 模仿干活System.out.println(Thread.currentThread().getName() + " put end");lock.unlock(); // 解锁} catch (InterruptedException e) {e.printStackTrace();}}
}

运行结果如下(每次运行结果一样的,仔细体会一下):

Thread-0 get begin
Thread-0 get end
Thread-1 get begin
Thread-1 get end
Thread-2 put begin
Thread-2 put end
Thread-3 put begin
Thread-3 put end

转载于:https://my.oschina.net/u/215547/blog/809379

Java并发编程 - 显示锁Lock和ReentrantLock相关推荐

  1. Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...

  2. Java并发编程之锁机制之LockSupport工具

    关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章<Java并发编程之锁机制之AQS(AbstractQueuedSynchronizer ...

  3. Java并发编程(06):Lock机制下API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Lock体系结构 1.基础接口简介 Lock加锁相关结构中涉及两个使用广泛的基础API:ReentrantLock类和Condition接 ...

  4. 6. Java并发编程-并发包-Lock和Condition

    前文介绍了java语言本身通过synchronized, wait, notify实现了管程,解决了并发编程两大难题:互斥和同步. 这两大问题并发包中也得到了相应的实现,分别时Lock和Conditi ...

  5. java并发锁有哪些,Java并发编程-公平锁与非公平锁

    写这个文章的时候让我想起了让子弹飞的一个台词 公平,公平,还是tmd公平! 什么是公平和非公平 首先,我们来看下什么是公平锁和非公平锁. 公平锁指的是按照线程请求的顺序,来分配锁: 非公平锁指的是不完 ...

  6. Java 并发编程—有锁互斥机制及AQS理论

    原文作者:Java并发编程 原文地址:AQS这样学就很简单了 目录 一.有锁互斥机制 二.AQS如何实现互斥 三.结语 如果你是道格李,你要实现一套机制来保证线程互斥,你会如何实现呢?你肯定不会一上来 ...

  7. Java并发编程—JUC的Lock锁

    一.Lock (JUC锁) JUC 锁位于java.util.concurrent.locks包下,为锁和等待条件提供一个框架,它不同于内置同步和监视器. CountDownLatch,CyclicB ...

  8. 【java】java 并发编程 StampedLock 锁 【不重要】

    文章目录 1.概述 2.synchronized 3.读写锁 3.1 读写锁缺点 4.StampedLock 4.1 缺点 5.案例 5.1 案例1 5.1 案例2 6.性能对比 7.总结 1.概述 ...

  9. Java并发编程—无锁互斥机制及CAS原理

    目录 一.CAS简介 二.AtomicInteger代码演示 三.CAS 实现 四.弊端 一.CAS简介 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令 ...

最新文章

  1. Java项目:在线商城系统(前后端分离+java+vue+Springboot+ssm+mysql+maven+redis)
  2. 1.4 正则化-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  3. 触摸屏通常接在微型计算机,计算机应用基础习题答案.doc
  4. Autowire异常
  5. vs 2008 Ide 设置
  6. ref和out的联系及区别(转)
  7. 第八节:ES6为数组做了哪些扩展?
  8. JS弹出可拖动层,并蒙住页面
  9. hdu 2604 Queuing AC自动机构造递推式-矩阵-结果
  10. RHEL6 kernel bug在hadoop上的测试
  11. Flash CS3无法导出测试影片问题解决
  12. 一人饮酒醉用计算机版,玩家自制游戏版《一人饮酒醉》,歪唱喊麦笑翻全场
  13. 特斯拉是如何训练自动驾驶的?
  14. Shaderlab 玻璃效果
  15. 用EXCEL宏编写坐标转换
  16. Memcached Redis构建缓存服务器
  17. 西安市2012年教师资格证考试报名时间:3月10-15日
  18. Linux各发行版的前世今生
  19. 蓝桥杯嵌入式(一)学习准备
  20. java导出excel

热门文章

  1. TensorFlow函数(十)tf.global_variables_initializer()
  2. 微信生态圈盈­利模式分析
  3. background-position 用法介绍
  4. 删除eclipse或者MyEclipse的workspace记录
  5. Python使用BeautifulSoup爬取网页中主体部分的内容,并导出为pdf格式
  6. IDEA查看Java类的UML关系图
  7. kotlin中mainactivity无法直接调用xml中的控件_使用Kotlin高效地开发Android App(一)
  8. 微服务模块综合管理(模块视图管理,自动化热部署,前端资源实时刷新......)
  9. seata不兼容mysql8的解决方案
  10. ORACLE不完全恢复的几种情况