Java 并发编程实战 摘要】的更多相关文章

第一部分小结 并发技巧清单: 可变状态是至关重要的(It's the mutable state ,stupid). 所有的并发问题结为如何协调对并发状态的访问,可变状态越少,就越容易确保线程安全性. 尽量将域声明为 final 类型, 除非需要它们是可变的. 不可变对象一定是线程安全的. * 不可变对象能极大地降低并发编程的复杂性.它们更为简单而且安全,可以任意共享而无须使用加锁或保护性复制等机制. 封闭有县城于管理复杂性. * 在编写线程安全的程序时,虽然可以将所有数据都保存在全局变量中,…
摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 并发Bug源头 在计算机系统中,程序的执行速度为:** CPU > 内存 > I/O设备 ** ,为了平衡这三者的速度差异,计算机体系机构.操作系统.编译程序都进行了优化: 1.CPU增加了缓存,以均衡和内存的速度差异 2.操作系统增加了进程.线程,已分时复用CPU,以均衡 CPU 与 I/O 设…
摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经常考核到) 什么是Java内存模型? 现在知道了CPU缓存导致可见性.编译优化导致了有序性问题,那么最简单的方式就是直接禁用CPU缓存和编译优化.但是这样做我们的性能可就要爆炸了~.我们应该按需禁用. Java内存模型是有一个很复杂的规范,但是站在程序员的角度上可以理解为:Java内存模型规范了JV…
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和有序性的问题,那么还有一个原子性问题咱们还没解决.在第一篇文章01并发编程的Bug源头当中,讲到了把一个或者多个操作在 CPU 执行的过程中不被中断的特性称为原子性,那么原子性的问题该如何解决. 同一时刻只有一个线程执行这个条件非常重要,我们称为互斥,如果能保护对共享变量的修改时互斥的,那么就能保住…
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头结点和尾节点,他们分别指向队列的头和尾,尝试获取锁.入队列.释放锁等实现都与头尾节点相关,并且每个节点都引入前驱节点和后后续节点的引用:在等待机制上由原来的自旋改成阻塞唤醒.其结构如下: 知道其结构了,我们再看看他的实现.在线程获取锁时会调用AQS的acquire()方法,该方法第一次尝试获取锁如果失败,会将…
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 lock方法,在调用acquireQueued(): if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; 在acquireQueued()中调用parkAndChec…
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInterruptibly(int arg): 以独占模式获取对象,如果被中断则中止. acquireShared(int arg): 以共享模式获取对象,忽略中断. acquireSharedInterruptibly(int arg)以共享模式获取对象,如果被中断则中止. tryAcquire(int…
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一组线程互相等待,直到到达某个公共屏障点,才会进行后续任务".而CountDownlatch和它也有一点点相似之处:CountDownlatch所描述的是"在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待".在JDK API中是这样阐述的: 用给定的计数 初始化…
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么介绍的: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用.因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier.…
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/读"."读/写"."写/写"操作都不能同时发生.然而在实际的场景中我们就会遇到这种情况:有些资源并发的访问中,它大部分时间都是执行读操作,写操作比较少,但是读操作并不影响数据的一致性,如果在进行读操作时采用独占的锁机制,这样势必会大大降低吞吐量.所以如果能够做…