在过去单核CPU时代,单任务在一个时间点只能执行单一程序,随着多核CPU的发展,并行程序开发就显得尤为重要。
本书主要介绍基于Java的并行程序设计基础、思路、方法和实战。,立足于并发程序基础,详细介绍Java中进行并行程序设计的基本方法。第二,进一步详细介绍JDK中对并行程序的强大支持,帮助读者快速、稳健地进行并行程序开发。第三,详细讨论有关“锁”的优化和提高并行程序性能级别的方法和思路。第四,介绍并行的基本设计模式及Java 8对并行程序的支持和改进。第五,介绍高并发框架Akka的使用方法。后,详细介绍并行程序的调试方法。
1. 结构清晰。本书一共8 章,总体上循序渐进,逐步提升。每一章都各自有鲜明的侧重点,有利于读者快速抓住重点。
2. 理论结合实战。本书注重实战,书中重要的知识点都安排了代码实例,帮助读者理解。同时也不忘记对系统的内部实现原理进行深度剖析。
3. 通俗易懂。本书尽量避免采用过于理论的描述方式,简单的白话文风格贯穿全书,配图基本上为手工绘制,降低了理解难度,并尽量做到读者在阅读过程中少盲点、无盲点。
海报
推荐购买:
《实战Java虚拟机——JVM故障诊断与性能优化》
葛一鸣:51CTO特约讲师,国家认证系统分析师,获得Oracle OCP认证。长期从事Java软件开发工作,对Java程序设计、JVM有深入的研究,对设计模式、人工智能、神经网络、数据挖掘等技术有浓厚兴趣,著有《自己动手写神经网路》电子书和《实战Java虚拟机》一书。
郭超:就职于杭州市道路运输管理局信息中心,主要从事大型交通管理系统的分布式管理和并发模型设计,对Java的研究比较深入,专注于分布式应用和并发应用。
第1章走入并行世界
1.1何去何从的并行计算
1.1.1忘掉那该死的并行
1.1.2可怕的现实:摩尔定律的失效
1.1.3柳暗花明:不断地前进
1.1.4光明或是黑暗
1.2你必须知道的几个概念
1.2.1同步(Synchronous)和异步(Asynchronous)
1.2.2并发(Concurrency)和并行(Parallelism)
1.2.3临界区
1.2.4阻塞(Blocking)和非阻塞(Non-Blocking)
1.2.5死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)
1.3并发级别
1.3.1阻塞(Blocking)
1.3.2无饥饿(Starvation-Free)
1.3.3无障碍(Obstruction-Free)
1.3.4无锁(Lock-Free)
1.3.5无等待(Wait-Free)
1.4有关并行的两个重要定律
1.4.1Amdahl定律
1.4.2Gustafson定律
1.4.3Amdahl定律和Gustafson定律是否相互矛盾
1.5回到Java:JMM
1.5.1原子性(Atomicity)
1.5.2可见性(Visibility)
1.5.3有序性(Ordering)
1.5.4哪些指令不能重排:Happen-Before规则
1.6参考文献
第2章Java并行程序基础
2.1有关线程你必须知道的事
2.2初始线程:线程的基本操作
2.2.1新建线程
2.2.2终止线程
2.2.3线程中断
2.2.4等待(wait)和通知(notify)
2.2.5挂起(suspend)和继续执行(resume)线程
2.2.6等待线程结束(join)和谦让(yield)
2.3volatile与Java内存模型(JMM)
2.4分门别类的管理:线程组
2.5驻守后台:守护线程(Daemon)
2.6先干重要的事:线程优先级
2.7线程安全的概念与synchronized
2.8程序中的幽灵:隐蔽的错误
2.8.1无提示的错误案例
2.8.2并发下的ArrayList
2.8.3并发下诡异的HashMap
2.8.4初学者常见问题:错误的加锁
2.9参考文献
第3章JDK并发包
3.1多线程的团队协作:同步控制
3.1.1synchronized的功能扩展:重入锁
3.1.2重入锁的好搭档:Condition条件
3.1.3允许多个线程同时访问:信号量(Semaphore)
3.1.4ReadWriteLock读写锁
3.1.5器:CountDownLatch
3.1.6循环栅栏:CyclicBarrier
3.1.7线程阻塞工具类:LockSupport
3.2线程复用:线程池
3.2.1什么是线程池
3.2.2不要重复发明轮子:JDK对线程池的支持
3.2.3刨根究底:核心线程池的内部实现
3.2.4超负载了怎么办:拒绝策略
3.2.5自定义线程创建:ThreadFactory
3.2.6我的应用我做主:扩展线程池
3.2.7合理的选择:优化线程池线程数量
3.2.8堆栈去哪里了:在线程池中寻找堆栈
3.2.9分而治之:Fork/Join框架
3.3不要重复发明轮子:JDK的并发容器
3.3.1超好用的工具类:并发集合简介
3.3.2线程安全的HashMap
3.3.3有关List的线程安全
3.3.4高效读写的队列:深度剖析ConcurrentLinkedQueue
3.3.5高效读取:不变模式下的CopyOnWriteArrayList
3.3.6数据共享通道:BlockingQueue
3.3.7随机数据结构:跳表(SkipList)
3.4参考资料
第4章锁的优化及注意事项
4.1有助于提高"锁"性能的几点建议
4.1.1减小锁持有时间
4.1.2减小锁粒度
4.1.3读写分离锁来替换独占锁
4.1.4锁分离
4.1.5锁粗化
4.2Java虚拟机对锁优化所做的努力
4.2.1锁偏向
4.2.2轻量级锁
4.2.3自旋锁
4.2.4锁消除
4.3人手一支笔:ThreadLocal
4.3.1ThreadLocal的简单使用
4.3.2ThreadLocal的实现原理
4.3.3对性能有何帮助
4.4无锁
4.4.1与众不同的并发策略:比较交换(CAS)
4.4.2无锁的线程安全整数:AtomicInteger
4.4.3Java中的指针:Unsafe类
4.4.4无锁的对象引用:AtomicReference
4.4.5带有时间戳的对象引用:AtomicStampedReference
4.4.6数组也能无锁:AtomicIntegerArray
4.4.7让普通变量也享受原子操作:AtomicIntegerFieldUpdater
4.4.8挑战无锁算法:无锁的Vector实现
4.4.9让线程之间互相帮助:细看SynchronousQueue的实现
4.5有关死锁的问题
4.6参考文献
第5章并行模式与算法
5.1探讨单例模式
5.2不变模式
5.3生产者-消费者模式
5.4高性能的生产者-消费者:无锁的实现
5.4.1无锁的缓存框架:Disruptor
5.4.2用Disruptor实现生产者-消费者案例
5.4.3提高消费者的响应时间:选择合适的策略
5.4.4CPU Cache的优化:解决伪共享问题
5.5Future模式
5.5.1Future模式的主要角色
5.5.2Future模式的简单实现
5.5.3JDK中的Future模式
5.6并行流水线
5.7并行搜索
5.8并行排序
5.8.1分离数据相关性:奇偶交换排序
5.8.2改进的插入排序:希尔排序
5.9并行算法:矩阵乘法
5.10准备好了再通知我:网络NIO
5.10.1基于Socket的服务端的多线程模式
5.10.2使用NIO进行网络编程
5.10.3使用NIO来实现客户端
5.11读完了再通知我:AIO
5.11.1AIO EchoServer的实现
5.11.2AIO Echo客户端实现
5.12参考文献
第6章Java 8与并发
6.1Java 8的函数式编程简介
6.1.1函数作为一等公民
6.1.2无副作用
6.1.3申明式的(Declarative)
6.1.4不变的对象
6.1.5易于并行
6.1.6更少的代码
6.2函数式编程基础
6.2.1FunctionalInterface注释
6.2.2接口默认方法
6.2.3lambda表达式
6.2.4方法引用
6.3一步一步走入函数式编程
6.4并行流与并行排序
6.4.1使用并行流过滤数据
6.4.2从集合得到并行流
6.4.3并行排序
6.5增强的Future:CompletableFuture
6.5.1完成了就通知我
6.5.2异步执行任务
6.5.3流式调用
6.5.4CompletableFuture中的异常处理
6.5.5组合多个CompletableFuture
6.6读写锁的改进:StampedLock
6.6.1StampedLock使用示例
6.6.2StampedLock的小陷阱
6.6.3有关StampedLock的实现思想
6.7原子类的增强
6.7.1更快的原子类:LongAdder
6.7.2LongAdder的功能增强版:LongAccumulator
6.8参考文献
第7章使用Akka构建高并发程序
7.1新并发模型:Actor
7.2Akka之Hello World
7.3有关消息投递的一些说明
7.4Actor的生命周期
7.5监督策略
7.6选择Actor
7.7消息收件箱(Inbox)
7.8消息路由
7.9Actor的内置状态转换
7.10询问模式:Actor中的Future
7.11多个Actor同时修改数据:Agent
7.12像数据库一样操作内存数据:软件事务内存
……
4.4.6数组也能无锁:AtomicIntegerArray
除了提供基本数据类型外,JDK还为我们准备了数组等复合结构。当前可用的原子数组有:AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray,分别表示整数数组、long型数组和普通的对象数组。
这里以AtomicIntegerArray为例,展示原子数组的使用方式。
AtomicIntegerArray本质上是对int[]类型的封装,使用Unsafe类通过CAS的方式控制int[]在多线程下的安全性。它提供了以下几个核心API:
//获得数组第i个下标的元素
public final int get(int i)
//获得数组的长度
public final int length()
//将数组第i个下标设置为newValue,并返回旧的值
public final int getAndSet(int i, int newValue)
//进行CAS操作,如果第i个下标的元素等于expect,则设置为update,设置成功返回true
public final boolean compareAndSet(int i, int expect, int update)
//将第i个下标的元素加1
public final int getAndIncrement(int i)
//将第i个下标的元素减1
public final int getAndDecrement(int i)
//将第i个下标的元素增加delta(delta可以是负数)
public final int getAndAdd(int i, int delta)4.4.6数组也能无锁:AtomicIntegerArray
除了提供基本数据类型外,JDK还为我们准备了数组等复合结构。当前可用的原子数组有:AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray,分别表示整数数组、long型数组和普通的对象数组。
这里以AtomicIntegerArray为例,展示原子数组的使用方式。
AtomicIntegerArray本质上是对int[]类型的封装,使用Unsafe类通过CAS的方式控制int[]在多线程下的安全性。它提供了以下几个核心API:
//获得数组第i个下标的元素
public final int get(int i)
//获得数组的长度
public final int length()
//将数组第i个下标设置为newValue,并返回旧的值
public final int getAndSet(int i, int newValue)
//进行CAS操作,如果第i个下标的元素等于expect,则设置为update,设置成功返回true
public final boolean compareAndSet(int i, int expect, int update)
//将第i个下标的元素加1
public final int getAndIncrement(int i)
//将第i个下标的元素减1
public final int getAndDecrement(int i)
//将第i个下标的元素增加delta(delta可以是负数)
public final int getAndAdd(int i, int delta)
下面给出一个简单的示例,展示AtomicIntegerArray的使用:
01 public class AtomicIntegerArrayDemo {
02 static AtomicIntegerArray arr = new AtomicIntegerArray(10);
03 public static class AddThread implements Runnable{
04 public void run(){
05 for(int k=0;k
06 arr.getAndIncrement(k%arr.length());
07 }
08 }
09 public static void main(String[] args) throws InterruptedException {
10 Thread[] ts=new Thread[10];
11 for(int k=0;k
12 ts[k]=new Thread(new AddThread());
13 }
14 for(int k=0;k
15 for(int k=0;k
16 System.out.println(arr);
17 }
18 }
上述代码第2行,申明了一个内含10个元素的数组。第3行定义的线程对数组内10个元素进行累加操作,每个元素各加1000次。第11行,开启10个这样的线程。因此,可以预测,如果线程安全,数组内10个元素的值必然都是10000。反之,如果线程不安全,则部分或者全部数值会小于10000。
程序的输出结果如下:
[10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000]
这说明AtomicIntegerArray确实合理地保障了数组的线程安全性。
好
整体感觉不错
纸质差点,但挺清晰的,好评
书很喜欢哟
这本书不错
还不错 很有用~
包装好,质量好,性价比超高,值得考虑。
赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞
很不错,内容充实,讲的都很专业
没有包塑料皮,其他书都有,公司有一本这个书,写的很好,所以自己就买了一本。实用性强,适用于至少有1年Java工作经验的人,是一本值得看多遍的书。(快递是指定周六周日送的,却周二送了,批评)
讲得并不深,还不如某些博客
赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞
赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞好
内容很好,讲的知识点比较全面,通俗易懂,循序渐进,就是错别字太多。
因为喜欢他的另一本书,性能优化的所以也要买下这本书,爱屋及乌
看了几章感觉还不错,实用技能类书籍还是很赞的。
我买个书居然给我发的是物流 结果还慢到死 如果下次当当发的还是这个物流直接退货
书写的不错, 适合没有多少并发经验的java程序员阅读, 结合源码看效果更棒
不错,之前看过很多原理性的东西,这次看一下在实际编码中的运用.
并发现在愈来愈重要,因此这本书的内容很重要
很好的一本书,介绍的知识非常有用,看的出来作者是用心写了。
程序员必看,没事买来拓展下知识,懂得多才值钱!
看了个开头,尽是引用的大佬理论。希望后面的内容多一些实用技巧。
看到“知其然,知其所以然”的人写的并发的书。虽然有少量的错别字,排版错误,整体瑕不掩瑜。
作者的功力很深,从jvm到并发的原理都有介绍,适合有Java经验的人
很好的一本书,讲的很好,比《java并发编程实战》更适合入门~个人愚见,希望对买家有帮助!
通俗易懂 除了图不是正规绘制之外,其他都不错~偶尔有错别字 无伤大雅 通向高级Java工程师的必经之路!