juc

JUC锁框架——基于AQS的实现,从ReentrantLock认识独占和共享

馋奶兔 提交于 2019-11-27 02:35:00
JDK中有以下基于AQS的实现 ReentrantLock CountDownLatch Semaphore ReentrantReadWriteLock CyclicBarrier (委托给ReentrantLock) 首先关于源码中经常出现 final ReentrantLock takeLock = this.takeLock 写法: 这是一个有关volatile变量的lock-free的典型习惯编码。在第一行第一次到读到变量后,另一个线程会更新这个值,但你只对初始读到的值感兴趣。 另外,即使我们讨论的成员变量不是 volatile而是final, 这个习惯用法也与CPU缓存有关:从栈读变量比从堆读变量会更cache-friendly,本地变量最终绑定到CPU寄存器的可能性更高。 ReentrantLock的独占和共享: 基本上一致,区别: 非公平锁是: 先state+1,然后直接得到锁, 而公平锁则是: 先尝试去获取锁,如果得到了锁则state+1. 实现公平性的关键在于:如果锁被占用且当前线程不是持有者也不是等待队列的第一个,则进入等待队列。 可见是否公平实际上是对处于等待队列中的线程来说的。 ReentrantLock都是把具体实现委托给内部类 而不是直接继承自AbstractQueuedSynchronizer, 这样的好处是用户不会看到不需要的方法,

Java并发指南16:JUC中常用的Unsafe和Locksupport

寵の児 提交于 2019-11-26 23:39:09
原创文章,转载请注明: 转载自 并发编程网 – ifeve.com 1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算1+2+。。+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和,最终汇总这10个子任务的结果。Fork/Join的运行流程图如下: 2. 工作窃取算法 工作窃取(work-stealing)算法是指某个线程从其他队列里窃取任务来执行。工作窃取的运行流程图如下: 那么为什么需要使用工作窃取算法呢?假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应,比如A线程负责处理A队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行

JUC AQS ReentrantLock源码分析(一)

爱⌒轻易说出口 提交于 2019-11-26 17:36:17
警告⚠️:本文耗时很长,先做好心理准备,建议PC端浏览器浏览效果更佳。 Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略,但是与Lock相比synchronized还是存在一些缺陷的:虽然synchronized提供了便捷性的隐式获取锁释放锁机制(基于JVM机制),但是它却缺少了获取锁与释放锁的可操作性,可中断、超时获取锁,且它为独占式在高并发场景下性能大打折扣。 如何自己来实现一个同步 自旋实现一个同步: volatile int status=0;//标识---是否有线程在同步块-----是否有线程上锁成功 void lock(){ while(!compareAndSet(0,1)){ } //lock } void unlock(){ status=0; } boolean compareAndSet(int except,int newValue){ //cas操作,修改status成功则返回true } 缺点:耗费cpu资源。没有竞争到锁的线程会一直占用cpu资源进行cas操作,假如一个线程获得锁后要花费Ns处理业务逻辑,那另外一个线程就会白白的花费Ns的cpu资源 解决思路:让得不到锁的线程让出CPU yield+自旋实现同步: volatile int

JUC之ReentrantLock

对着背影说爱祢 提交于 2019-11-26 14:32:44
JUC之ReentrantLock 文章目录 JUC之ReentrantLock 一、什么是ReentrantLock 二、ReentrantLock的实现 1、重入机制的实现 2、公平机制的实现 三、ReentrantLock的应用 一、什么是ReentrantLock ReentrantLock就是可重入锁,它主要实现了以下两种机制: 可重入,一个线程可以重复获取该锁。 公平性,它实现了公平锁与非公平锁。 前者能够解决饥饿问题,但是会耗费进百倍的性能 后者可能会造成饥饿问题,但是,性能更好。 可重入锁,它本身是一个独占锁。 二、ReentrantLock的实现 1、重入机制的实现 解决重入问题 protected final boolean tryAcquire ( int acquires ) { final Thread current = Thread . currentThread ( ) ; int c = getState ( ) ; //计数为0,无需解决重入问题,直接CAS获取 if ( c == 0 ) { if ( ! hasQueuedPredecessors ( ) && compareAndSetState ( 0 , acquires ) ) { setExclusiveOwnerThread ( current ) ; return true ;

JUC之ReadWriteLock

◇◆丶佛笑我妖孽 提交于 2019-11-26 14:31:42
JUC之读写锁解读 文章目录 JUC之读写锁解读 一、什么是读写锁 二、读写锁的实现 三、升降级 1、锁降级 2、锁升级 四、使用场景 一、什么是读写锁 ​ 读写锁实现的功能就是“读写分离”,读可以并发读,写只能串行写,同时,读的时候不能写,写的时候不能读。但是,如何控制读与写,需要我们手动在读代码块上加读锁,写代码上加写锁。 二、读写锁的实现 ​ 这里我主要讲一些内部实现原理。 读为共享锁 final boolean tryReadLock ( ) { Thread current = Thread . currentThread ( ) ; for ( ; ; ) { int c = getState ( ) ; //判断是否此时有写锁。 if ( exclusiveCount ( c ) != 0 && getExclusiveOwnerThread ( ) != current ) return false ; //读锁的共享数量 int r = sharedCount ( c ) ; if ( r == MAX_COUNT ) throw new Error ( "Maximum lock count exceeded" ) ; //尝试CAS if ( compareAndSetState ( c , c + SHARED_UNIT ) ) { if ( r == 0

JUC之原子类

时光总嘲笑我的痴心妄想 提交于 2019-11-26 10:20:57
JUC原子类 文章目录 JUC原子类 一、分类 二、基本类型 1、AtomicInteger 2、AtomicLong 3、AtomicBoolean 三、数组类型 1、AtomicIntegerArray 四、引用类型 1、AtomicReference 2、AtomicReferenceArray 五、对象属性类型 1、AtomicIntegerFieldUpdater(抽象类) demo 一、分类 Juc原子类可以分为以下四大类: 基本类型 AtomicInteger, AtomicLong, AtomicBoolean 数组类型 AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray 引用类型 AtomicReference, AtomicStampedRerence, AtomicMarkableReference 对象属性类型 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater 二、基本类型 1、AtomicInteger public class AtomicInteger extends Number implements java . io . Serializable { private