reentrantlock

ReentrantLock

百般思念 提交于 2019-12-01 07:19:37
在了解ReentrantLock之前,我们首先回忆一下 synchronized ,synchronized是java内置的关键字,锁的获取和释放都是由jvm实现,因此用户就不需要显示的去释放锁,是一种独占的加锁方式,但是虽然方便,也有一定的弊端: 1.当线程尝试获取锁的时候,如果获取不到锁会一直阻塞,这个阻塞的过程,用户无法控制 2.如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待 接下来我们还需要了解几个相关的概念: 可重入锁 :可重入锁是指同一个线程可以多次获得同一把锁; ReentrantLock和关键字Synchronized都是可重入锁 。 可中断锁 :可中断锁时只线程在获取锁的过程中,是否可以相应线程中断操作。 synchronized是不可中断的 , ReentrantLock是可中断的 。 公平锁和非公平锁 :公平锁是指多个线程尝试获取同一把锁的时候,获取锁的顺序按照线程到达的先后顺序获取,而不是随机插队的方式获取。 synchronized是非公平锁 ,而 ReentrantLock是两种都可以实现,不过默认是非公平锁 1.ReentrantLock的使用方式 public class Demo { ReentrantLock lock = new ReentrantLock(); public static int num

【JUC】3.ReentrantLock

二次信任 提交于 2019-12-01 05:10:48
【JUC】3.ReentrantLock ReentrantLock实2477203708现Lock接口,所以先看下Lock接口: public interface Lock { // 获得锁 void lock(); // 获得锁 void unlock(); // lock非阻塞版本,成功返回true boolean tryLock(); // 添加尝试时间,时间到返回false boolean tryLock(long time, TimeUnit unit) // 返回一个监视器对象 Condition newCondition(); } 再来看ReentrantLock的常用API: public class ReentrantLock implements Lock,Serializable { // 构造器,可以实现公平锁 public ReentrantLock() public ReentrantLock(boolean fair) public void lock() // 可中断锁 public void lockInterruptibly() // 可轮询的锁获取,有返回值。获取成功返回true;获取失败,返回false,线程不会阻塞、 public boolean tryLock() public boolean tryLock(long timeout,

Java 并发之 AbstractQueuedSynchronizer

前提是你 提交于 2019-12-01 04:45:09
如果你读过 JUC 中 ReentrantLock、CountDownLatch、FutureTask、Semaphore 等的源代码,会发现其中都有一个名为 Sync 的类,而这个类是以 AbstractQueuedSynchronizer 为基础的,所以说 AbstractQueuedSynchronizer 是 JUC 的基础之一(注:CyclicBarrier 并没有直接以 AQS 为基础)。出于知其然也要知其所以然的目的,我学习了 AQS 的实现原理,并总结成此文。 数据结构 在 AQS 中,有两个重要的数据结构,一个是 volatile int state,另一个是 class Node 组成的双向链表。 int state 顾名思义,这个变量是用来表示 AQS 的状态的,例如 ReentrantLock 的锁的状态和重入次数、FutureTask 中任务的状态、CountDownLatch 中的 count 计数等等。这个值的更新都是由 AQS compareAndSetState 方法来实现的,而这个方法则是通过 Compare and Swap 算法实现,至于这个算法的细节就不多说了。在 JDK 中,这个算法是由 Native 方法实现的。 Node 双向链表 Node 是 AQS 的一个内部类,主要有 waitStatus、prev、next、thread

java并发-ReentrantLock的lock和lockInterruptibly的区别

跟風遠走 提交于 2019-12-01 01:44:52
ReentrantLock的加锁方法Lock()提供了无条件地轮询获取锁的方式,lockInterruptibly()提供了可中断的锁获取方式。这两个方法的区别在哪里呢?通过分析源码可以知道lock方法默认处理了中断请求,一旦监测到中断状态,则中断当前线程;而lockInterruptibly()则直接抛出中断异常,由上层调用者区去处理中断。 1 lock操作 lock获取锁过程中,忽略了中断,在成功获取锁之后,再根据中断标识处理中断,即selfInterrupt中断自己。 acquire操作源码如下: /** *默认处理中断方式是selfInterrupt */ public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } acquireQueued,在for循环中无条件重试获取锁,直到成功获取锁,同时返回线程中断状态。该方法通过for循正常返回时,必定是成功获取到了锁。 /** *无条件重试,直到成功返回,并且记录中断状态 */ final boolean acquireQueued(final Node node, int arg) { boolean failed = true;

Condition give the effect of having multiple wait-sets per object?

▼魔方 西西 提交于 2019-12-01 01:23:30
I am reading about Condition in java.util.concurrent.locks.Condition . Condition factors out the Object monitor methods (wait, notify and notifyAll) >into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Can somebody explain me this? How this is a benefit over normal synchronization blocks or method? One Lock can be associated with many Conditions. Lock is an "object", each condition is a "waiting set". This allows for independent conditions sharing critical section. For example, consider bounded

为什么JDK代码这样写?final ReentrantLock takeLock = this.takeLock

喜你入骨 提交于 2019-11-30 19:12:53
在CopyOnWriteArrayList的源码中有一个细节值得学习,就是在addIfAbsent方法中ReentrantLock的用法,先是将一个这个成员变量this.lock重新赋值给一个局部变量lock之后再使用它,貌似跟java的内存模型有关,具体说明参考这篇文章:https://www.jianshu.com/p/04236d63f055 public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { final transient ReentrantLock lock = new ReentrantLock(); private boolean addIfAbsent(E e, Object[] snapshot) { // 开发过程中尽量将全局变量重赋给局部变量,尤其用局部变量做循环的情况 // 会一定程度上提升性能,也应该是代码的一般原则(general principle)。 final ReentrantLock lock = this.lock; lock.lock(); try { ...... ...... } finally { lock.unlock(); } } } 来源: https://www

Java并发锁控制API详解

落爺英雄遲暮 提交于 2019-11-30 18:12:18
Java并发锁控制API详解 博客分类: 多线程与并发 JAVA 一.Lock接口(java.util.concurrent.locks): void lock():获取锁,阻塞方式;如果资源已被其他线程锁定,那么lock将会阻塞直到获取锁,锁阻塞期间不受线程的Interrupt的影响,在获取锁成功后,才会检测线程的interrupt状态,如果interrupt=true,则抛出异常。 unlock():释放锁 tryLock():尝试获取锁,并发环境中"闯入"行为,如果有锁可用,直接获取锁并返回true,否则范围false. lockInterruptibly():尝试获取锁,并支持"中断"请求。与lock的区别时,此方法的开始、结束和执行过程中,都会不断检测线程的interrupt状态,如果线程被中断,则立即抛出异常;而不像lock方法那样只会在获取锁之后才检测。 二.Lock接口实现类 Lock直接实现,只有3个类: ReentrantLock和WriteLock/ReadLock; 这三种锁;Lock和java的synchronized(内置锁)的功能一致,均为排他锁. ReentrantLock为重入排他锁,对于同一线程,如果它已经持有了锁,那么将不会再次获取锁,而直接可以使用. ReentrantReadWriteLock并没有继承ReentrantLock

源码分析Java并发(JUC框架)专栏

☆樱花仙子☆ 提交于 2019-11-30 07:48:29
java多线程是JAVA高阶编程最需掌握的基本功,本系列从源码的角度对JUC(java 并发工具包)进行详细剖析,一起探讨java多线程并发相关知识。 1、 java并发锁ReentrantLock源码分析一 可重入支持中断锁的实现原理 2、 java并发锁机制-ReentrantLock Condtion准备篇之Object.wait,Object.notify与Condtion 3、 java并发锁ReentrantLock源码分析二之Condition实现原理 4、 java并发锁ReentrantReadWriteLock读写锁源码分析 5、 java并发容器ConcurrentHashMap源码分析 6、 Queue队列API与源码分析优先级队列PriorityQueue实现原理 7、 java多线程Thread join与CountDownLatch源码分析 8、 java并发编程之源码分析ThreadPoolExecutor线程池实现原理 来源: CSDN 作者: 唯有坚持不懈 链接: https://blog.csdn.net/prestigeding/article/details/103246606

java并发编程之重入锁

心不动则不痛 提交于 2019-11-30 06:09:28
重入锁可以完全替代synchronized关键字,在JDK 5.0早期版本中,重入锁的性能远远好于synchronzied,但是在6.0之后在synchronzied上做了大量的优化,使两者的差距并没那么大的差别。 重入锁使用java.util.concurrent.locks.ReentrantLock类来实现,它只是一个类; 且看如下代码: package cn.yan.current; import java.util.concurrent.locks.ReentrantLock; public class ReenterLock implements Runnable { private static ReentrantLock lock = new ReentrantLock(); public static int i = 0; @Override public void run() { for (int j = 0; j < 30000; j++) { lock.lock(); try { i++; } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { ReenterLock reenterLock = new

深度解读ReentrantLock底层源码

梦想的初衷 提交于 2019-11-30 05:46:19
目录 ReentrantLock简介 基础知识铺垫 state属性 线程持有者属性 ReentrantLock中的队列使用 Demo&原理解析 公平锁-lock()方法 Demo 详尽原理 白话原理(面试口述) unLock()方法 详尽原理 白话原理(面试口述) 公平锁-lock()方法 Demo 详尽原理 白话原理(面试口述) lockInterruptibly()方法 Demo 详尽原理 白话原理(面试口述) tryLock()方法 Demo 详尽原理 白话原理(面试口述) tryLock(long timeout, TimeUnit unit)方法 Demo 详尽原理 白话原理(面试口述) 面试题汇总 ReentrantLock全中文注释可运行源码下载 原文地址: https://gitbook.cn/gitchat/activity/5d80202b5fb33e7ca5da4437 ReentrantLock简介 ​ jdk并发包中的可重入锁,是基于AQS(AbstractQueuedSynchronized)实现的,它有公平锁(线程上锁的顺序完全基于调用方法的先后顺序)和不公平锁(线程上锁的顺序不完全基于调用方法的先后顺序)两种实现方式。 ​ ReentrantLock提供多种API:公平锁/非公平锁-lock()方法、定时释放锁-tryLock(long