reentrantlock

Why is lock captured to a local variable

三世轮回 提交于 2019-12-10 16:05:41
问题 In java JRE I saw the code private final ReentrantLock lock; public E poll() { final ReentrantLock lock = this.lock; lock.lock(); Why is lock captured to a private variable? I would expect simply public E poll() { lock.lock(); 回答1: Primarily it is to ensure maximum performance. Although this is a real micro-optimisation, it's probably in performance-sensitive code, and you might as well make it. You also need to be very careful that the lock reference you are using doesn't mutate. Sure make

synchronized和ReentrantLock区别

*爱你&永不变心* 提交于 2019-12-10 03:10:05
一.什么是 sychronized sychronized是java中最基本同步互斥的手段,可以修饰代码块,方法,类. 在修饰代码块的时候需要一个reference对象作为锁的对象. 在修饰方法的时候默认是当前对象作为锁的对象. 在修饰类时候默认是当前类的Class对象作为锁的对象. synchronized会在进入同步块的前后分别形成monitorenter和monitorexit字节码指令.在执行monitorenter指令时会尝试获取对象的锁,如果此没对象没有被锁,或者此对象已经被当前线程锁住,那么锁的计数器加一,每当monitorexit被锁的对象的计数器减一.直到为0就释放该对象的锁.由此synchronized是可重入的,不会出现自己把自己锁死. 二.什么ReentrantLock 以对象的方式来操作对象锁.相对于sychronized需要在finally中去释放锁 三.synchronized和ReentrantLock的区别 除了synchronized的功能,多了三个高级功能. 等待可中断,公平锁,绑定多个Condition. 1.等待可中断 在持有锁的线程长时间不释放锁的时候,等待的线程可以选择放弃等待. tryLock(long timeout, TimeUnit unit) 2.公平锁 按照申请锁的顺序来一次获得锁称为公平锁

ReenTrantLock可重入锁(和synchronized的区别)总结

混江龙づ霸主 提交于 2019-12-09 11:00:57
ReenTrantLock可重入锁(和synchronized的区别)总结 可重入性: 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入的,两者关于这个的区别不大。两者都是同一个线程没进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。 锁的实现: Synchronized是依赖于JVM实现的,而ReenTrantLock是JDK实现的,有什么区别,说白了就类似于 操作系统 来控制实现和用户自己敲代码实现的区别。前者的实现是比较难见到的,后者有直接的源码可供阅读。 性能的区别: 在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReenTrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。 功能区别: 便利性:很明显Synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁

Lock的实现之ReentrantLock详解

丶灬走出姿态 提交于 2019-12-09 10:59:08
摘要 Lock在硬件层面依赖CPU指令,完全由Java代码完成,底层利用LockSupport类和Unsafe类进行操作; 虽然锁有很多实现,但是都依赖AbstractQueuedSynchronizer类,我们用ReentrantLock进行讲解; ReentrantLock调用过程 ReentrantLock类的API调用都委托给一个内部类 Sync ,而该类继承了 AbstractQueuedSynchronizer类; public class ReentrantLock implements Lock, java.io.Serializable { ...... abstract static class Sync extends AbstractQueuedSynchronizer { ...... 而Sync又分为两个子类:公平锁和非公平锁,默认为非公平锁 /** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { /** * Sync object for fair locks */ static final class FairSync extends Sync { Lock的调用过程如下图(其中涉及到 ReentrantLock类、Sync(抽象类)

ReentrantLock实现原理深入探究

杀马特。学长 韩版系。学妹 提交于 2019-12-09 10:58:53
前言 这篇文章被归到Java基础分类中,其实真的一点都不基础。网上写ReentrantLock的使用、ReentrantLock和synchronized的区别的文章很多,研究ReentrantLock并且能讲清楚ReentrantLock的原理的文章很少,本文就来研究一下ReentrantLock的实现原理。研究ReentrantLock的实现原理需要比较好的Java基础以及阅读代码的能力,有些朋友看不懂没关系,可以以后看,相信你一定会有所收获。 最后说一句,ReentrantLock是基于AQS实现的,这在下面会讲到,AQS的基础又是CAS,如果不是很熟悉CAS的朋友,可以看一下这篇文章 Unsafe与CAS 。 AbstractQueuedSynchronizer ReentrantLock实现的前提就是AbstractQueuedSynchronizer,简称AQS,是java.util.concurrent的核心,CountDownLatch、FutureTask、Semaphore、ReentrantLock等都有一个内部类是这个抽象类的子类。先用两张表格介绍一下AQS。第一个讲的是Node,由于 AQS是基于FIFO队列的实现 ,因此必然存在一个个节点,Node就是一个节点,Node里面有: 属 性 定 义 Node SHARED = new Node()

ReentrantLock代码剖析之ReentrantLock.lock

别说谁变了你拦得住时间么 提交于 2019-12-09 10:58:33
ReentrantLock 是 java.util.concurrent.locks 中的一个可重入锁类。在高竞争条件下有更好的性能,且可以中断。深入剖析 ReentrantLock 的源码有助于我们了解线程调度,锁实现,中断,信号触发等底层机制,实现更好的并发程序。 先来看 ReentrantLock 最常用的代码lock public void lock() { sync.lock(); } 很简单,直接调用了成员变量 sync 的 lock 方法。以下是 sync 的声明 /** Synchronizer providing all implementation mechanics */ private final Sync sync; 从注释中我们可以看出sync提供了所有的实现机制,ReentrantLock只是简单执行了转发而已。 下图是Sync的层次结构,Sync,FairSync和NonFairSync都是ReentrantLock的静态内部类。Sync 是一个抽象类,而FairSync和NonFairSync则是具体类,分别对应了公平锁和非公平锁。实际中公平锁吞吐量比非公平锁小很多,所以以下讨论若非特别说明均以非公平锁为例。 在上图的类层次中,最核心的类当属AbstractQueuedSynchronizer

Java并发ReentrantLock

心不动则不痛 提交于 2019-12-09 10:58:13
ReentrantLock简介 可重入锁,作用是使线程安全。对比于 sychronized ,它能具有以下特点 减小资源锁的力度 更可控,减少发生死锁的概率 加锁、释放锁都是显示控制的 添加锁的作用时间来防止发生死锁 更加灵活 重入锁 可重入锁可以理解为锁的一个标识。该标识具备计数器功能。标识的初始值为0,表示当前锁没有被任何线程持有。每次线程获得一个可重入锁的时候,该锁的计数器就被加1。每次一个线程释放该所的时候,该锁的计数器就减1。前提是:当前线程已经获得了该锁,是在线程的内部出现再次获取锁的场景 ReentrantLock扩展功能 实现可轮询的锁请求 在内部锁中,要恢复死锁的唯一方法就是重启应用;而通过ReentrantLock可以规避死锁的发生 如果你不能获得所有需要的锁,那么使用可轮询的获取方式使你能够重新拿到控制权,它会释放你已经获得的这些锁,然后再重新尝试。可轮询的锁获取模式,由 tryLock()方 法实现。 此方法仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值true。如果锁不可用,则此方法将立即返回值false。 ```java /*Acquires the lock only if it is not held by another thread at the time of invocation. */ lock.tryLock() `

Java并发编程(二)

那年仲夏 提交于 2019-12-09 10:58:04
1、Lock接口 在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的,在Java SE 5 后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized类似的同步功能,只是在 使用时需要显示地获取和释放锁 。虽然缺少了隐式获取释放锁的便捷性,但是却 拥有 了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种 synchronized 关键字所 不具有的同步特性 。 2、Lock接口主要特性 尝试非阻塞地获取锁 :当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。 能被中断地获取锁 :与synchronized不同,获取到锁的线程能响应中断,当获取到锁的线程被中断时,中断异常将会抛出,且锁会被释放。 超时获取锁 :在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回。 Lock接口的实现基本都是通过 聚合了一个同步器的子类 来完成 线程访问控制 的。 3、队列同步器 队列同步器(AbstarctQueuedSynchronizer),是用来 构建锁 或者 其他同步组件 的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。 同步器既可以支持独占式地获取同步状态,也可以支持共享式地获取同步状态

Java并发之ReentrantLock详解

China☆狼群 提交于 2019-12-09 10:57:23
一、入题 ReentrantLock是Java并发包中互斥锁,它有公平锁和非公平锁两种实现方式,以lock()为例,其使用方式为: ReentrantLock takeLock = new ReentrantLock(); // 获取锁 takeLock.lock(); try { // 业务逻辑 } finally { // 释放锁 takeLock.unlock(); }    那么,ReentrantLock内部是如何实现锁的呢?接下来我们就以JDK1.7中的ReentrantLock的lock()为例详细研究下。 二、ReentrantLock类的结构 ReentrantLock类实现了Lock和java.io.Serializable接口,其内部有一个实现锁功能的关键成员变量Sync类型的sync,定义如下:    /** Synchronizer providing all implementation mechanics */ private final Sync sync;    而这个Sync是继承了AbstractQueuedSynchronizer的内部抽象类,主要由它负责实现锁的功能。关于AbstractQueuedSynchronizer我们会在以后详细介绍,你只要知道它内部存在一个获取锁的等待队列及其互斥锁状态下的int状态位(0当前没有线程持有该锁

java并发系列(三)-----ReentrantLock(重入锁)功能详解和应用演示

纵然是瞬间 提交于 2019-12-09 10:56:11
1. ReentrantLock简介 jdk中独占锁的实现除了使用关键字synchronized外,还可以使用ReentrantLock。虽然在性能上ReentrantLock和synchronized没有什么区别,但ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。 2. ReentrantLock和synchronized的相同点 2.1 ReentrantLock是独占锁且可重入的 例子 public class ReentrantLockTest { public static void main(String[] args) throws InterruptedException { ReentrantLock lock = new ReentrantLock(); for (int i = 1; i <= 3; i++) { lock.lock(); } for(int i=1;i<=3;i++){ try { } finally { lock.unlock(); } } } } 上面的代码通过 lock() 方法先获取锁三次,然后通过 unlock() 方法释放锁3次,程序可以正常退出。从上面的例子可以看出,ReentrantLock是可以重入的锁,当一个线程获取锁时,还可以接着重复获取多次