Java并发
文章平均质量分 90
GDUT_Ember
这个作者很懒,什么都没留下…
展开
-
Java并发(十三):读写锁之间的锁降级和锁升级
回顾锁降级锁降级的必要性锁升级回顾之前已经分析了读写锁之间是如何进行加锁的,下面就看看,读写锁之间怎么进行锁降级与锁升级的锁降级读写锁的锁降级指的是写锁降级成为了读锁当一个线程获取了写锁,并且又获取了读锁(获取写锁的线程可以获取读锁),那么当该线程释放了写锁时,该线程拥有的锁就会进行降级,变为了读锁,其实这个实现从之前看加锁源码就知道了,读锁和写锁的获取都是分开的,所以写锁的释放不会影响到读锁的持有锁降级的必要性锁降级的情景是,拿了写锁,然后再拿读锁,这有什么必要性吗?拿了写锁我就进行修改了.原创 2021-10-16 11:28:01 · 1694 阅读 · 3 评论 -
Java并发(十一):读写锁——写锁
概述ReentrantReadWriteLock特性使用方法读写锁的实现分析如何使用位拆分去表示两种锁的重入状态呢?如何判断读锁和写锁获取写锁写锁的获取lock方法tryAcquiregetExclusiveOwnerThreadexclusivesetState写锁的释放tryRelease概述ReentrantLock和Mutex都是一个排他锁,也就是说,同一时刻只有一个线程可以去获取这把锁但读写锁并不完全是排他锁,同一时刻是允许多个读线程来进行访问的,读写锁实际上指的是一对锁,读锁和写锁读锁.原创 2021-10-16 11:27:16 · 981 阅读 · 0 评论 -
Java并发(十二):读写锁——读锁
回顾读锁读锁的获取tryAcquireShared记录各个线程的重入次数HoldCounterreadHolds.getsetInitialValue方法set方法假如第一次获取失败回顾前面我们已经看了写锁是怎样进行获取和释放的,下面就来看看读锁的获取和释放读锁写锁是一个排他锁,而读锁却是一个共享锁,而且还支持可重入,并且能被多个线程同时获取读锁的获取可以看到,其底层的实现也是AQS,只不过是AQS的共享模式,并且执行的是AQS的acquireShared方法源码如下 publi.原创 2021-10-16 11:22:11 · 535 阅读 · 0 评论 -
Java并发容器(二):Java并发容器和框架--ConcurrentLinkedQueue(JDK1.7)
并发安全的队列实现ConcurrentLinkedQueue结构拥有的变量属性Node类构造方法入队操作出队操作updateHead方法源码并发安全的队列实现ConcurrentLinkedQueue是一个线程安全的队列,队列的并发不安全性其实也就是会出现覆盖的问题而实现一个线程安全的队列有两种方式去实现,其实总的来说是拥有两种算法一种是阻塞算法,也就是用锁去控制队列的入队和出队,可以是两个锁也可以是一个锁另外一种就是非阻塞算法,采用循环CAS的方式去实现,其实也就是乐观锁而Concurr.原创 2021-09-04 11:36:36 · 164 阅读 · 0 评论 -
Java并发容器(一):Java并发容器和框架--ConcurrencyHashMap(JDK1.7)
ConcurrentHashMap的实现原理与使用(JDK1.7)ConcurrentHashMap可以理解成是一个并发安全的HashMap在并发编程中,HashMap是不安全的,会导致一个死循环的问题,还有一个并发安全的HashTable,但使用HashTable的效率非常低下(加Synchronic),于是就出现了ConcurrentHashMap线程不安全的HashMap在并发编程中,使用HashMap进行put操作是会引起死循环的,最终结果就会导致CPU利用率接近100%下面分析一下为什么原创 2021-08-30 22:48:22 · 274 阅读 · 0 评论 -
Java并发(十):独占式超时获取同步状态
独占式超时获取同步状态doAcquireNanosspinForTimeoutThresholdparkNanoscancalAcquire前面已经看过了整个独占式锁的获取锁与解锁过程,但其实在AQS里面,对于独占式锁是可以设置超时获取锁的,也就是一旦在队列中等待了指定时间后都没有拿到锁,就放弃去获取锁独占式超时获取同步状态对应的方法为tryAcquireNanos,尝试获取有超时时间的锁,注意:Nanos代表的是纳秒参数里面有一个arg,这个参数是传给tryAcquire与doAcquireN.原创 2021-06-19 12:04:27 · 287 阅读 · 0 评论 -
Java并发(十):独占式、共享式的获取与释放
Lock接口队列同步器AbstractOwnableSynchronizer实现分析同步队列底层结点状态结点插入保证线程安全独占式同步状态的获取与释放共享式同步状态获取与释放共享式同步tryAcquireShareddoAcquireSharedsetHeadAndPropagatedoReleaseShared共享式释放tryReleaseShared前面我们认识了ReentrantLock(可重入锁)可Java里面不止一种锁,所以下面来了解一下Java里面有什么锁Lock接口在Lock接口出现.原创 2021-06-18 16:39:35 · 480 阅读 · 0 评论 -
Java并发(九):延迟初始化的两种解决方案、认识类初始化过程中的同步机制
volatile解决重排序问题类初始化解决重排序问题类初始化过程中的同步机制第一阶段第二阶段第三阶段第四阶段第五阶段volatile与类初始化的两个方案之间存在什么区别下面我们来谈一下双重检查锁定与延迟初始化volatile解决重排序问题在前面学习懒汉模式实现单例模式的时候,我们已经使用过下面的这一套优化流程了代码块中加锁判断单例对象是否已经初始化如果已经初始化,直接返回单例对象再进行判断多一次单例对象是否已经初始化,来判断单例模式对象是否已经初始化,因为可能同时有多个线程判断出单例对.原创 2021-06-17 17:38:02 · 474 阅读 · 1 评论 -
Java并发(八):final域的内存语义
final域的重排序规则写final域的重排序规则读final域的重排序规则final域的引用类型为什么final引用不能从构造函数内溢出?即发生重排序final的底层实现final这个修饰可以加在类、方法、变量上加在类上面是让类不可以被继承,而且里面的方法全部默认为final修饰加在方法上是让该方法不可以被子类重写加在变量上,表示该变量变为常量,而且必须进行初始化但其实final也是可以解决一些并发重排序问题的。final域的重排序规则final域也有自己的重排序规则在构造函数来对.原创 2021-06-17 16:18:04 · 108 阅读 · 0 评论 -
# Java并发(七):锁的内存语义
锁的释放和获取的内存语义锁的释放锁的获取与volatile的读写内存语义比较锁内存语义的实现在Java里面,锁除了让临界区互斥外,还可以让释放锁的线程向获取同一个锁的线程发送消息锁的释放和获取的内存语义接下来,看一下线程在锁的释放和获取究竟对内存是怎样的操作锁的释放当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中锁的获取当线程获取锁时,JMM会把该线程对应的本地内存置为无效,从而使得被监视器monitor保护的临界区代码必须从主内存中读取共享变量(前面已经提到过,s.原创 2021-06-17 13:38:02 · 77 阅读 · 0 评论 -
Java并发(六):ReentrantLock的解锁过程
unlock方法release方法tryRelease方法unparkSuccessor方法前面我们已经了解过了加锁过程,下面就来看看解锁的过程是怎样的这里提一下,公平锁和非公平锁的解锁过程是一样的unlock方法解锁调用的就是unlock方法可以看到其调用的还是内部类sync的方法,而且可以看到这是一个无返回值的方法并且传入了一个为1的参数release方法可以看到,其调用的是AQS里面的release方法步骤如下先调用tryRelease方法,尝试进行解锁然后判断是否需要.原创 2021-06-17 10:31:35 · 236 阅读 · 0 评论 -
Java并发(五):ReentrantLock的加锁实现——公平锁
ReentrantLockAQS的底层AQS的变量、常量与内部类Node内部类FairSync:公平锁lock方法AbstractQueuedSynchronizer的acquire方法tryAcquire方法getState方法hasQueuedPredecessors方法setExclusiveOwnerThread方法总结tryAcquire方法返回AbstractQueuedSynchronized的acquire方法acquireQueued方法setHeadshouldParkAfterFai.原创 2021-06-16 22:47:44 · 1257 阅读 · 0 评论 -
Java并发(四):volatile的内存语义
volatile可见性实验volatile的特性volatile 写与读的内存语义写语义读语义总结一下读写语义volatile的实现volatile的内存语义实现前面我们已经讲过了volatile的作用、底层实现与内存屏障下面就总结一下整个流程volatile可见性实验举个栗子我这里开了两个线程,后面的线程去修改volatile变量,前面的线程不断获取volatile变量,结果是会一致卡在死循环,控制台没有任何输出假如将flag让volatile来进行修饰结果是:三秒后,就不会不断打印.原创 2021-06-14 18:25:21 · 1479 阅读 · 2 评论 -
Java并发(三):重排序与内存一致性
happens-before重排序数据依赖性as-if-serial语义重排序对多线程的影响顺序一致性同步程序不同步程序上面一篇已经讲了一下指令重排序与内存屏障究竟是怎么回事下面就来研究一下重排序与内存一致性happens-beforehappens-before是一种关系,在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系,注意,这里的两个操作既可以是不同线程,也可以是同一个线程那happens-before有什么规则了程序.原创 2021-06-14 12:34:26 · 310 阅读 · 0 评论 -
Java并发(二):原子操作的实现原理与Java内存模型
原子操作的实现原理总线锁定缓存锁定Java的原子操作实现循环时间开销大只能保证一个共享变量的原子操作Java内存模型Java内存模型的抽象结构指令重排序原子操作的实现原理处理器使用总线锁定和缓存锁定这两个机制来保证复杂内存操作的原子性总线锁定我们来分析一下i++当多个线程去执行i++的时候,是会出现并发问题的,因为i++并不是一个原子的操作,它分为三步,典型的读改写操作从内存中读取i的值,并且存储到线程本地内存中线程根据本地内存的副本执行加1然后将副本写回到内存中并发的问题就在于,当.原创 2021-06-13 15:57:49 · 203 阅读 · 1 评论 -
Java并发(一):volatie与synchronized实现原理
上下文切换如何减少上下文切换CAS算法ABA问题Java并发机制底层实现Volatile关键字线程可见性防止指令重排序volatie的实现缓存行自动填充synchronized关键字synchronized底层实现java代码层级上字节码层级上Java对象内存布局对象头锁状态无锁偏向锁轻量级锁重量级锁三种锁的比较上下文切换多线程是通过CPU给每个线程分配CPU时间片来实现的,所以本质上CPU只能执行一个线程而不能执行多个,多线程其实就是CPU在不断地切换线程去执行,让外界感觉像是多个在同时运行多线程.原创 2021-06-12 23:06:30 · 3233 阅读 · 8 评论