并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能。它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰、思维缜密,这样才能写出高效、安全、可靠的多线程并发程序。
衡量一名“程序猿”的技术实力,一般会看你是否具备深度的系统性能调优的能力。云计算的时代,对系统的高性能、高并发要求更高。所以,深入了解和掌握Java的多线程机制原理,非常有用,非常必要。
笔记尽量减少“哕嗦"式的文字语言,全部用Demo式案例来讲解技术点的实现,使读者看到代码及运行结果后就可以知道此项目要解决的是什么问题。类似于网络中Blog的风格,可让读者用最短的时间学会此知识点,明白此知识点如何应用,以及在使用时要避免什么。这就像“瑞士军刀”,虽短小,却锋利。笔记的目的就是帮读者快速学习并解决问题。
这本书的所有知识均来自于作者多年的项目实践,倾注了作者多年的心血。讲解的深入浅出,让你掌握起来毫不费力。如果你想成为一名架构师, 如果你想成为一名资深的技术大牛,强烈推荐你读一读, 你值得拥有!
读者对象
笔记特点
内容简介
第1章Semaphore和Exchanger的使用
类Semaphore的主要作用是限制并发执行的线程个数,它具有synchronized 所不具有的强大功能,比如等待获得许可的同时可以加入等待时间,还有尝试是否可以持有锁等这类扩展功能,可以说Semaphore类是强有力的控制并发线程个数的解决方案之一, 而Exchanger是线程间传输数据的方式之一, 而且在传输的数据类型上并没有任何限制。
第2章CountDownLatch和CyclicBarrier的使用
本章主要介绍了CountDownLatch、CyclicBarrier 这两个类的使用,使用CountDown-Latch类可以实现两种角色的线程等待对方的效果,而CyclicBarrier类可以使同类线程互相等待达到同步的效果,使用这两个类可以更加完善地实现线程对象之间的同步性,对线程对象执行的轨迹控制更加方便。
第3章Phaser的使用
类Phaser提供了动态增减parties计数,这点比CyclicBarrier类操作parties更加方便,通过若干个方法来控制多个线程之间同步运行的效果,还可以实现针对某一个线 程取消同步运行的效果,而且支持在指定屏障处等待,在等待时还支持中断或非中断等功能,使用Java并发类对线程进行分组同步控制时,Phaser 比CyclicBarrier类功能更加强大,建议使用。
第4章Executor与ThreadPoolExecutor的使用
本章主要介绍ThreadPoolExecutor类的构造方法中各个参数的作用与使用效果,还介绍了Executors 工厂类常用API的使用,也将大部分ThreadPoolExecutor线程池类的常见API一同进行了介绍,并且对ThreadPoolExecutor线程池的拒绝策略进行了实验,通过使用线程池能最大幅度地减少创建线程对象的内存与CPU开销,加快程序运行效率,也对创建线程类的代码进行了封装,方便开发并发类型的软件项目。
第5章Future和Callable的使用
本章对Future和Callable接口中的全部API进行了介绍,这两个接口的优点就是从线程中返回数据以便进行后期的处理,但FutureTask类也有其自身的缺点,就是阻塞性,解决这个缺点请参看第6章。
第6章CompletionSernvice的使用
接口CompletionService完全可以避免FutureTask类阻塞的缺点,可更加有效地处理Future的返回值,也就是哪个任务先执行完,CompletionService 就先取得这个任务的返回值再处理。
第7章接口ExecutorService的方法使用
接口ExecutorService中的方法都以便携的方式去创建线程池,使用两个主要的方法invokeAny(和invokeAll0来取得第一个首先执行完任务的结果值,以及全部任务的结果值。
第8章计划任务ScheduledExecutorService的使用
本章介绍了基于线程池ThreadPoolExecutor的ScheduledThreadPoolExecutor计划任务执行池对象,使用此类可以高效地实现计划任务线程池,不再重复创建Thread对象,提高了运行效率。此类也支持间隔运行的功能。
第9章Fork-Join分治编程
在本章主要介绍了Fork-Join 分治编程类主要的API,需要细化掌握ForkJoinTask的2个常用子类的fork分解算法,虽然分治编程可以有效地利用CPU资源,但不要为了分治编程而分治,应该结合具体的业务场景来进行使用。
第10章并发集合框架
本章主要介绍了Java并发包中的集合框架,集合在使用Java语言中是非常重要的技能点,而并发集合框架在原来功能的基础上进行再次强化,完全支持多线程环境下的数据处理,大大提高了开发效率,有效保证了数据的存储结构,以常见的阻塞与非阻塞算法加强并发包中功能的可用性。
Java并发编程无处不在,服务器、数据库、应用,Java并发是永远不可跳过的沟坎,优秀的程序员一定要在Java并发领域进行炼狱式的学习,吸收消化并最终转化成软件产品成果。另外,单纯从Java程序员成长计划这方面进行考虑,Java多线程/并发也依然是想深入学习Java必须要掌握的技术,比如在软件公司中接触的“缓存”,”分布式一致性”,"高并发框架”,“海量数据处理”,“高效订单处理”等都与Java多线程、Java并发紧密相关。进行大数据、分布式、高并发类的专题攻克时,并发编程的学习必不可少,但并发编程学习曲线陡峭,多弯路和“坑”。本书基本完全覆盖了Java并发包中核心类、API与并发框架,最大程度介绍了每个常用类的使用,以案例的方式进行讲解,以使读者快速学习,迅速掌握。
由于内容太多就不一一展示了 ,这4份并发编程手册分别为226、370、431、422页,需要完整版的朋友,可以点赞此文关注小编,【见下图】获取!!
无论如何,开发、测试、调试多线程的程序仍然非常困难:常见的情形总是开发的并发程序看上去可以正常工作,但是在极端情况下就会失败,就生产环境而言这种情况是指高负载。《JAVA 并发编程实践》以坚实的理论基础和翔实的实践技术,帮助读者构建可靠的、可伸缩的和可维护的并发应用程序。本书并不是简单地罗列出并发API和机制,相反,它提供了设计规则、模式和理想模型,使读者能够更容易地构建出既正确又高效的并发程序来。
内容简介
线程安全
一个对象是否应该是线程安全的取决于它是否会被多个线程访问。线程安全的这个性质,取决于程序中如何使用对象,而不是对象完成了什么。保证对象的线程安全性需要使用同步来协调对其可变状态的访问;若是做不到这一点,就会导致脏数据和其他不可预期的后果。
无论何时,只要有多于一个的线程访问给定的状态变量,而且其中某个线程会写入该变量,此时必须使用同步来协调线程对该变量的访问。Java 中首要的同步机制是synchronized关键字,它提供了独占锁。除此之外,术语“同步”还包括volatile 变量,显示锁和原子变量的使用。
你会想到在一些“特殊”情况下上述规则并不适用,不过你应该抵制住这种想法的诱惑。程序如果忽略了必要的同步,可能看上去可以运行,而且能够通过测试,甚至能正常地运行数年,但它仍然是存在隐患的,任何时刻都有可能崩溃。
共享对象
我们在第2章开始的时候提到过,编写正确的并发程序的关键在于对共享的、可变的状态进行访问管理。上一章是关于使用同步来避免多个线程在同一时间访问同一数据的: 这一章详细讲述共享和发布对象的技术,使多个线程能够安全地访问他们。这两章合在一起,可以作为构建线程安全类,以及使用java.util.concurrent类库构造安全的并发应用程序的基础。
组合对象
到目前为止,我们已经介绍了线程安全与同步的基础知识。但是我们不希望为了获得线程安全而去分析每次内存访问;而希望线程安全的组件能够以安全的方式组合成更大的组件或程序。这一章介绍 了一些构造类的模式,这些模式让类更容易成为线程安全的,并且不会让程序意外破坏这些类的线程安全性。
构建块
上一章探究了一些关于构造线程安全类的技术,包括将线程安全性委托给现有的线程安全类。在实践中,委托是创建线程安全类最有效的策略之一:只需要用已有的线程安全类来管理所有状态即可。
任务执行
大多数并发应用程序是围绕执行任务(ask)进行管理的。所谓任务就是抽象、离散的工作单元(unit of work)。把一个应用程序的工作(work)分离到任务中,可以简化程序的管理:这种分离还在不同事务间划分了自然的分界线,可以方便程序在出现错误时进行恢复;同时这种分离还可以为并行工作提供一个自然的结构,有利于提高程序的并发性。
取消和关闭
启动任务和线程都很容易。大多数时候,我们通常允许它们在结束任务后自行停止。但是,有时候我们希望在任务或线程自然结束之前就停止它们,可能因为用户取消了操作,或者应用程序需要快速关闭。
应用线程池
第6章介绍的任务执行框架,可以简化任务与线程生命周期的管理。它提供一种简便、灵活的方式,可以在任务的提交与任务的执行策略之间解耦。第7章包含一些繁杂的细节内容,包括了在真实的应用程序中使用任务执行框架的生命周期服务。本章关注在配置和调整线程池时用的高级选项,讲述了使用任务执行框架的过程中需要注意的危险,还提供了一些使用Executor更高级的例子。
GUI应用程序
几乎所有的GUI工具集都实现为单线程化子系统(single threaded),意味着所有GUI的活动都被限制在一个单 独的线程中,这其中就包括了Swing和SWT.如果你没有打算写一个完全 单线程化的程序,就会有一些活动部分运行在事件线程中, 部分运行在另一个应用程序线程中。像其他与线程相关的bug-一样, 这种错误的分割并不会导致你的应用程序立即崩溃;你的程序会在一些难 以发现的条件下出现古怪的行为.GUI框架自身是单线程子系统,可能你的应用程序还不是,那么编写GUI代码的时候,你需要仔细地考虑线程问题。
避免活跃度危险
安全性和活跃度通常相互牵制。我们使用锁来保证线程安全,但是滥用锁可能引起锁顺序死锁(lock-ordering deadlock)。类似地,我们使用线程池和信号量来约束资源的使用,但是却不能知晓那些管辖范围内的活动可能形成的资源死锁(resource deadlock)。Java应用程序不能从死锁中恢复,所以确保你的设计能够避免死锁出现的先决条件是非常有价值的。这一章将讲述一些引发活跃度失败的原因,以及避免发生这些失败的方法。
性能和可伸缩性
使用线程最主要的原因是提高性能。使用线程可以使程序更加充分地发挥出闲置的处理能力,从而更好地利用资源:并能够使程序在现有任务正在运行的情况下立刻开始着手处理新的任务,从而提高系统的响应性。
测试并发程序
并发程序在设计上采用与顺序程序大致相同的原则和模式。不同的是并发程序存在定程度的不确定性,顺序程序却没有这个问题。这样的不确定性增加了潜在的交互和失败模式的数量,我们必须为此做好计划和分析。
显式锁
在Java5.0之前,用于调节共享对象访问的机制只有synchroni zed和volatileeJava5.0提供了新的选择: ReentrantLock. 与我们已经提到过的机制相反,ReentrantLock并不是作为内部锁机制的替代,而是当内部锁被证明受到局限时,提供可选择的高级特性。
构建自定义的同步工具
类库中包含了大量依赖于状态(state -dependent)的类一这些类拥有基于状态的先验条件——FutureTask、Semaphore和BlockingQueue。 例如,你不能从一个空队列中移除条目,也不能从一个尚未结束的任务中获取结果;在这些操作可以执行前,你必须等到队列进入“非空”状态,任务进入“完成”状态。
原子变量与非阻塞同步机制
java . util. concurrent包中的许多类,比如Semaphore和ConcurrentLinkedQueue,都提供了比使用S)synchronized更好 的性能和可伸缩性。这一章, 我们来学 习这些性能提升的原始来源:原子变量和非阻塞的同步机制。
Java存储模型
纵观全书,我们已经最大程度地避开了Java存储模型(JMM)的底层细节,一直在关注高层的设计问题,比如安全发布、规约,以及遵守同步策略等等。它们的安全性得益于JMM,当你理解了为什么这些机制会如此工作后,能发现可以更容易有效地使用它们。本章中,我们会揭开Java存储模型的神秘面纱,看一看它的底层条件和它提供的保证,其间还会涉及一些本书讲过的高层设计原则背后的原理。
关注细节求本质,把握机会促发展。
道可顿悟,事须渐修: 一切从基础做起。一点一滴地慢慢积累。
安全两字很重要,不能忘记也不能丢。万一你把它忘了。程序就会出Bug.
知识是学出来的,能力是练出来的。
投入多少,收获多少:参与多深,领悟多深。
联强一跃,不能十步,驽马十驾。功在不舍。
卓越是方向,成就在路上。
不登高山,不知山之高。不临深渊,不知地之厚也。
鸟欲高飞先展翅,人求上进先读书。
很多事情不是看到希望了才去坚持,而是坚持了才会看到希望。学习也是如此。
JVM的参数
专家评测
特色
阅读对象
内容简介
阅读本书之前,你必须有-定的Java基础和开发经验,最好还有-定的并发编程基础。如果你是一名并发编程初学者,建议按照顺序阅读本书,并按照书中的例子进行编码和实战。如果你有一定的并发编程经验,可以把本书当做一个手册, 直接看需要学习的章节。以下是各章节的基本介绍。
第1章并发编程的挑战
并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题、死锁的问题,以及受限于硬件和软件的资源限制问题,本章会介绍几种并发编程的挑战以及解决方案。
第2章Java并发机制的底层实现原理
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令。本章我们将深入底层-起探索下Java并发机制的底层实现原理。
第3章Java内存模型
Java线程之间的通信对程序员完全透明,内存可见性问题很容易困扰Java程序员,本章将揭开Java内存模型神秘的面纱。本章大致分4部分:Java内存模型的基础,主要介绍内存模型相关的基本概念;Java内存模型中的顺序-致性,主要介绍重排序与顺序一致性内存模型;同步原语,主要介绍3个同步原语(synchronized、volatile和final)的内存语义及重排序规则在处理器中的实现;Java内存模型的设计,主要介绍Java内存模型的设计原理,及其与处理器内存模型和顺序一致性内存模型的关系。
第4章Java并发编程基础
Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势。线程作为操作系统调度的最小单元,多个线程能够同时执行,这将显著提升程序性能,在多核环境中表现得更加明显。但是,过多地创建线程和对线程的不当管理也容易造成问题。本章将着重介绍Java并发编程的基础知识,从启动一个线程到线程间不同的通信方式,最后通过简单的线程池示例以及应用(简单的Web服务器)来串联本章所介绍的内容。
第5章Java中的锁
本章将介绍Java并发包中与锁相关的API和组件,以及这些API和组件的使用方式和实现细节。内容主要围绕两个方面:使用,通过示例演示这些组件的使用方法以及详细介绍与锁相关的API;实现,通过分析源码来剖析实现细节,因为理解实现的细节方能更加得心应手且正确地使用这些组件。希望通过以上两个方面的讲解使开发者对锁的使用和实现两个层面有一定的了解。
第6章Java并发容器和框架
Java程序员进行并发编程时,相比于其他语言的程序员而言要倍感幸福,因为并发编程大师DougLea不遗余力地为Java开发者提供了非常多的并发容器和框架。本章让我们一起来见识一下大师操刀编写的并发容器和框架,并通过每节的原理分析一起来学习如何设计出精妙的并发程序。
第7章Java中的13个原子操作类
因为变量的类型有很多种,所以在Atomic包里一共提供了13个类,属于4种类型的原子更,新方式,分别是原子更新基本类型、原子更新数组、原子更新引用和原子更新属性(字段)。Atomic包里的类基本都是使用Unsafe实现的包装类。
第8章Java中的并发工具类
在JDK的并发包里提供了几个非常有用的并发工具类。CountDownL atch、CyclicBarrier和Semaphore工具类提供了一种 并发流程控制的手段,ExchangerI 具类则提供了在线程间交换数据的一种手段。本章会配合-些应用场景来介绍如何使用这些工具类。
第9章Java中的线程池
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处。
还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是,要做到合理利用线程池,必须对其实现原理了如指掌。
第10章Executor框架
在Java中,使用线程来异步执行任务。Java线程的创建与销毁需要一定的开销, 如果我们为每一个任务创建-个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源。同时,为每一个任务创建-个新线程来执行,这种策略可能会使处于高负荷状态的应用最终崩溃。
Java的线程既是工作单元,也是执行机制。从JDK 5开始,把工作单元与执行机制分离开来。工作单元包括Runnable和Callable,而执行机制由Executor框架提供。
第11章Java并发编程实践
当你在进行并发编程时,看着程序的执行速度在自己的优化下运行得越来越快,你会觉得越来越有成就感,这就是并发编程的魅力。但与此同时,并发编程产生的问题和风险可能也会随之而来。本章先介绍几个并发编程的实战案例,然后再介绍如何排查并发编程造成的问题。
本章介绍了使用生产者和消费者模式进行并发编程、线上问题排查手段和性能测试实战,以及异步任务池的设计。并发编程的实战需要大家平时多使用和测试,才能在项目中发挥作用
由于内容太多就不一一展示了 ,这4份并发编程手册分别为226、370、431、422页,需要完整版的朋友,可以点赞此文关注小编,【见下图】来获取!!
专家评测