《Java 并发编程的艺术》迷你书
本文源自InfoQ发表的《Java 并发编程的艺术》电子书 作者:方腾飞 序言:张龙 免费下载此迷你书
推荐序
欣闻腾飞兄弟的《聊聊并发》系列文章将要集结成InfoQ迷你书进行发布,我感到非常的振奋。这一系列文章从最开始的发布到现在已经经历了两年多的时间,这两年间,Java世界发生了翻天覆地的变化。Java 7已经发布,而且Java 8也将在下个月姗姗来迟。围绕着JVM已经形成了一个庞大且繁荣的生态圈,Groovy、Scala、Clojure、Ceylon等众多JVM语言在蓬勃发展着,如今的Java已经不是几年前的Java了,众多运行在JVM上的编程语言为我们带来了更多的选择,提供了更好的机会。
纵观这几年的技术发展趋势,唱衰Java的论调一直都萦绕在我们耳边。不可否认,Java的发展确实有些缓慢,而且有些臃肿;但放眼望去,有如此之多的核心与关键系统依旧在使用Java进行开发并运行在JVM之上,这不仅得益于Java语言本身,强大的JVM及繁荣的Java生态圈在这其中更是发挥着重要的作用。在Java的世界中,我们想要完成一件事情有太多可用的选择了。
虽然如此,对于国内的一些开发人员来说,但凡提到Java,想到的都是所谓的SSH(Struts、Spring及Hibernate等相关框架)。不可否认,这些框架对于我们又快又好地完成任务起到了至关重要的推进作用,然而Java并不是SSH,SSH也不是Java的代名词。
由于之前的系列文章都是本人审校的,因此我也非常幸运地成为了这些文章的第一个读者,在阅读之际不禁感叹腾飞的技术造诣及对技术执着的追求。腾飞兄弟的《聊聊并发》系列文章从发布以来一直高居InfoQ中文站浏览量的前列,每篇文章之后都有大量的读者评论,或是提问,或是补充相关知识,腾飞兄弟也都非常耐心地对读者的问题进行解答。并发是一个学科,Java中也有自己的一套处理并发的框架与体系;不过遗憾的是,很多读者对这一领域知之甚少,这也直接造成了很多人并不了解有关并发的理论与实践知识。幸运的是,腾飞的《聊聊并发》系列文章非常完美地填补了这一空白,文章从synchronized关键字、volatile实现原理到ConcurrentHashMap、ConcurrentLinkedQueue源码分析,再到阻塞队列和Fork/Join框架,为读者献上了一道丰盛的Java并发大餐。
相信腾飞以在淘宝的实际工作经验凝结而成的这部InfoQ迷你书会为广大读者打开通往Java并发之路的大门。这里我要小声做一个提示,也许文章中很多内容看一次未必就能完全消化吸收,这时请不要放弃,多看几次,多动手做实验,相信你会很快掌握Java并发的精髓的。
另外,值得一提的是,腾飞兄弟现在在维护着一个关于Java并发资源的站点——并发编程网(http://ifeve.com/),上面有大量高质量的原创与翻译文章,都是关于并发领域相关内容的,感兴趣的读者不妨移步一观。
最后,祝大家阅读愉快,能够轻松驾驭Java并发。
是为序。
InfoQ中文站Java主编:张龙
本书节选了成书的两个章节,完整版将由机械工业出版社华章公司于2015年发售,完整阅读需耐心等待。
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《Java 并发编程的艺术》迷你书
恭喜恭喜,加油方兄!!!
我运行这段代码:
final HashMap map = new HashMap(2);
Thread t = new Thread(new Runnable() {
public void run() {
for(int i = 0;i <1000;i++){
new Thread(new Runnable() {
public void run() {
map.put(UUID.randomUUID().toString(), "");
}
}, "ftf" + i).start();
}
}
}, "ftf");
t.start();
t.join();
并未发现CPU使用率近100%,维持在50%左右,而是直接内存溢出,这是为何呢?
内存溢出应该和这短代码没关系。
博主,我用JDK 8(b129, Mac 10.9)运行了上面的代码,第一次运行报错:ClassCastException(关于TreeNode和Node转换的,感觉像是JDK自身的问题),但是重新运行就正常了。
而且没有死循环出现,可能是JDK8对HashMap改造以后不会出现这个问题了,期待博主抽空研究下,thanks,特别是JDK8的ConcurrentHashMap,看的有点晕。
您好,方老师,请问下您有并发编程相关的视频教程么?在哪里可以购买到?
期待完整版上市
期待阅读
刚看了下迷你书的ConcurrentHashMap的部分,关于再哈希的原因描述,觉得有点不太恰当,单从理论上来讲,对一个哈希值再次哈希,不可能改良这个哈希值,只可能增加碰撞机率,ConcurrentHashMap之所以再哈希,是因为它使用哈希值的时候,只使用了其中的一部分bit,所以才需要再次哈希,将所有bit都加入计算,来减少部分bit相同时引发的碰撞。后面你也提到了它是如何使用那个哈希值的,但如果把这与前面结合起来讲,我觉得可能更方便读者理解。
深入jvm,和之前的java并发编程等书籍相比,本书的卖点是什么?
没有卖点
这本书,一定会买。
谢谢支持
期待啊,不知道什么时候会出完整版?
争取明年初
亲,这本书什么时候出啊,等了好久了。 。。!有具体日期么 !?
预计5月份,基本已经写完了,正在编辑
已经发布了
你好,我现在正在看java并发编程的艺术,在concurrentLinkedQueue一节中在入队列时获取p节点的下一个节点的succ方法中
final Node succ(Node p){
Node next = p.getNext();
return (p == next) ? head :next;
}
这里你说获取tail节点的next节点需要注意的是p节点等于p的next节点的情况,只有一种可能就是p节点和p的next节点都等于空
这里在创建concurrentLinkedQueue对象时
public ConcurrentLinkedQueue() {
head = tail = new Node(null);
}
已经初始化了tail节点,p怎么可能还为空呢,还有p如果为空,p.getNext()这里会报空指针啊???
想了一天也没想明白为什么p.getNext能和p相等,我觉得应该是p.getNext和p.getItem相等啊
求解答!!!万分感谢
很是期待完整,可惜要5月份啊
我还是买一本吧。
现在可以买到全书了吗?
还不能,还在校对中
什么时候可以买到啊
6月份了,全书快出来了吧
已出版
7月份了,方腾兄书还没出吗?
正在出版中,预计七月份预售,八月份能到读者手中。
以入手,书很不错。
你好,99页的WaitNotify.java 有些理解上的问题,Wait类的run方法中使用了代码块同步,用的是lock的监视器锁。Notify类的run方法也使用了lock监视器锁的代码块。WaitThread线程先执行,那么应该是先拿到lock的监视器锁,NotifyThread应该会因为拿不到监视器锁而阻塞啊,为什么程序会能正常执行完?
你好,Java8 ConcurrentHashMap做了蛮多的改动,有没有考虑专门写一篇文章对书中的CHM那一章进行一些改进。
您好,您在第一章中说到了线程切换时切换了上下文,请问这个“上下文”包含了哪些信息以及切换时都做了哪些操作?
请问下《Java并发编程的艺术中》
第二章,第2.1节 第10页
Lock前缀指令导致在执行指令期间,【声言】处理器的LOCK#信号。
这里【声言】是什么意思,本意是想说声明么?
请问《Java 并发编程艺术中》
第二章,第2.2节第9页:”……Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存”
那么 lock addl $0x0,(%esp); 就是 StoreLoad barriers 本身,要将当前处理器写缓冲区中的数据全部刷新到内存中。
到底哪个是对的呢,我应该修改一下书中第二章的内容吗
如果程序正确同步,程序的执行结果与在顺序一致性内存模型中的执行结果相同。
而对一个 volatile 域的写,happens-before 于任意后续对这个 volatile 域的读
Java语言规范:对volatile变量v的写入与任何线程对变量v的所有后续读取同步
于是 volatile 写不仅仅是一个变量所在缓存块被写回到系统内容,而是所有共享变量所在缓存块被写回到系统内容???
还是说写缓冲区中的数据全部被刷新到内存中,并且确保该volatile变量所在缓存行被写回到系统内容?
第二章第九页的内容其实还缺一部分,是这样的吧
Doug Lea 不是说 StoreLoad 屏障有其他延迟的实现吗。 MESI 协议,刷新 store buffer 是刷新到高速缓存中,既然是高速缓存应该无法通过嗅探机制来无效缓存,那么 volatile 读仍然要使用 MESI 的 read-barrier 来保证其他 CPU 的所有写入对于当前 CPU 是可见的不是吗
不是,Doug Lead 写的 StoreLoad 屏障也没说刷新到内存啊。。。
emm…但是好像这样理解也可以,但是实现和 MESI 好矛盾
明白了,作者这里还有内存屏障的文章啊
我弄混了,x86 StoreLoad 屏障的实现是回写到内存,并且x86 并没有 MESI 的 invalidate queue 概念。评论撤回不了了
经过我的仔细思考,书中对 StoreStore 和 StoreLoad 屏障的描述:”确保 Store1 数据加对其他处理器变得可见(指刷新到内存)”,还有 “因为当前处理器通常要把写缓冲区中的数据全部刷新到内存中(buffer fully flush)”
应该改成 “确保 Store1 数据加对其他处理器变得可见(例如刷新到内存)”,”因为当前处理器通常要对写缓冲区进行一个彻底的刷新(buffer fully flush)”
java并发编程的艺术第10页讲到,Lock前缀指令会引起处理器缓存回写到内存, 而处理器缓存回写到内存,会通过总线嗅探导致其他处理器的缓存无效。第41页说到volatile写会把共享变量的值刷新回主存,volatile读取时把本地内存置为无效。 这里如何理解,volatile变量缓存失效实质上是在写的时候发生的还是读的时候发生的? 如果是读的时候发生的, 那写一次变量, 后面读10次就会失效十次, 显然不太合理吧?
书有编写错误