Java并发编程学习路线

一年前因为工做须要从微软技术栈入坑Java,并陆陆续续作了一个Java后台项目,目前在搞Scala+Java混合的后台开发,一直以为并发编程是全部后台工程师的基本功,因此也学习了小一年Java的并发工具,对总体的并发理解乃至分布式都有必定的提升,因此想和你们分享一下。java

个人学习路线程序员

首先说说学习路线,我一开始是直接上手JCIP(Java Concurrency in Practice),发现不是很好懂,把握不了那本书的主线,因此思索着从国内的做者开始先,因此便读了下方腾飞的《Java并发编程的艺术》的,虽然豆瓣上的评价通常,可是对于构建Java并发的总体映像仍是有所提升的,至少我知道了有哪些东西要深刻学习。接着我想增强下并发的理论,继续读了The Art of Multiprocessor Programming,这本书比较艰涩,不是很好懂,可是过一遍仍是好处多多,建议初学者了解下概念的过过,后期能够再来翻看。有了以上两步的支持,接下来就又开始啃JCIP了,发现比之前有了不一样的感受,我能比较轻松的跟上书的脉络,知道书的总体框架,读起来不那么费劲了,这本书号称Java并发编程的圣经,确实能够看出做者有很丰富的并发实践经验。再后来我过了一遍Oracle官网上的Java Tutorial关于并发的那一章,发现讲的也不错,对于了解基础库有哪些组件帮助挺大。编程

到了这一步,接下来怎么继续提升呢?我发现了一本颇有趣的书,《七周七并发模型》,以前的视野一直是在Java并发编程的工具包中深刻了解,感受,应该跳出来,从模型的角度看看各个语言的并发实现的原理,我目前正处于这一步,发现颇有意思,第一章讲Java的线程和锁这个模型就感受很精髓,只用了小三章把Java总体的脉络过了一遍,强烈推荐用来复习。缓存

下一步个人计划是jdk的concurrent包以及Java specification的并发部分,并发理解,除了基础概念,就是要深入领会各个应用场景下,有无并发问题以及如何写出线程安全的代码,我的以为学习下无锁的实现对理解有必定的帮助,但不用太费心思,到了Java Memory Model这一层基本就够用了。安全

根据上面的阐述,个人路线图能够总结以下:数据结构

学习心得 -- Java并发包的基础概念多线程

了解Java并发包有哪些工具以及相关基础概念,有Java tutorial的concurrent章节和JCIP一书就足够了。并发

JCIP一书的总体脉络以下:oracle

  1. 介绍多线程的利弊;
  2. 解释线程安全是什么以及如何得到线程安全;
  3. 从高频的使用场景出发,介绍对象传递,类的设计等如何得到线程安全;
  4. 从Java并发包出发,介绍高层的并发组件有啥以及相关原理;
  5. 介绍并发的一些弊端以及如何避免;
  6. 从Java并发包出发,介绍底层的并发组件以及原理;

整体看,该书有两条主线,1 从高到低介绍Java并发包的一些重要组件和原理; 2 从并发场景出发,介绍如何利用这些组件来得到线程安全。其中第二部分是这本书最大的特点,也是书名中有Practice的缘由。框架

书中提到了几个比较有意思的地方,

首先,到底什么是线程安全?

A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.
这个定义中,做者强调了正确地被多线程访问, 同时要求没有外加其余同步的手段。

那么,如何得到线程安全?
Writing thread-safe code is, at its core, about managing access to state, and in particular to shared, mutable state.
书中将得到线程安全总结为维护代码的状态,若是一个类是无状态的(immutable),则自带线程安全的属性(函数式编程即是经过这种方式达到自带的线程安全)。这些状态大体能够理解为类中的很是量变量。 
经过这个能够了解到线程安全的本质,实际上是共享变量,也就是状态,有状态的多线程访问就须要同步机制来保证线程安全。

如何理解Java提供的用于处理并发的组件?
JDK提供的并发组件,大体能够分为两类, 一类是预防为主,防止错误发生(race condition, visibility),大部分组件都是这类,还有一类是发生了错误可是可以知道并及时重试(Atomic类提供的CAS),形象的例子有如 十字路口的信号灯,在流量小的时候,采用过多的预防措施反而会拔苗助长,例如白白的在大部分时间都没有车的道路上等红灯,这个时候适合采用犯错(例如去掉红绿灯,让车自由行驶,遇到其余车的时候互相让位便可)后解决的方法,可以得到最大的效率,在流量大的时候,红绿灯的做用就可以凸显出来,其实规则的制定必定是在规模较大的时候才有意义,这也是预防的初衷。
类比到并发领域就是,在线程数量大,采用预防的措施比较好,这样大部分线程就不会由于几率小的CAS重试浪费大量的cpu周期,在线程数量小的时候,CAS的意义就比较大,由于预防措施带来的线程切换等的开销可能大于CAS的等待,并且较少的线程也会让CAS重试的等待时间变少。

如下是我根据这两个资料归纳出来的基础概念,

理解这些基础概念的核心,我以为其实就是解决两点问题:

  • Thread Interleaving,即多个线程读写共享变量形成的不一致问题;
  • Visibility,为了提升性能,处理器的每一个执行单元其实都有缓存,这个虽然提升了某些数据的访问性能可是却给并发编程带来了数据读取的不一致性问题;

固然要更深刻理解并发,还须要知道如何提高并发的性能,例如锁的粒度如何把握?(经典的例子能够JDK的ConcurrentHashMap),底层一点的知识也得了解,例如CAS和Java Memory Model。

从高维视角了解并发

有了Java并发的基础知识,接下来很适合阅读七周七并发,我目前就在读七周七并发,发现站在多种语言从范式的角度了解并发颇有意思,原来Java提供的线程和锁的机制其实至关于比较原始的工具了,其离底层最近。最近接触了Scala,其使用了AKKA,则是一种高层的并发抽象。

七周七并发试图从历史的角度阐述做为锁和线程的表明之Java的并发包的进化历程,首先最先加入JDK的,实际上是synchronized及其statement,可是发现缺乏相关timeout和不能中断等等功能,加入了可重入锁,读写锁等等,再后来又加入了各类线程安全的数据结构和高级同步机制。

接下来,七周七并发从函数式编程等等各类范式的角度阐述,除了线程和锁,还有不少其余高层抽象能够更加方便的编写并发代码。

这本书对于充分理解并发,拓宽视野颇有帮助,推荐你们阅读。

从实现角度透彻理解并发

再深刻下去的话,没有比经典的JDK更合适的了,固然Google的Guava包也值得学习,从这些经典代码了解各类组件的实现能够加深理解并更好的使用它们,可是做为应用端的程序员,却是并不须要写出这种较为底层的代码(无锁化)。

回顾这小一年的学习曲线,收获良多,不过最后最值得强调的一点实际上是,在作技术选择的时候,并发只是工具箱中的一种手段,学习它只是为了可以灵活运用,设计的首要选择依然是在当时情境下的最简化,能不用并发就不要用。

相关文章
相关标签/搜索