前言:
Java并发编程学习分享的目标:
Java并发编程中常用的工具用途与用法;
Java并发编程工具实现原理与设计思路;
并发编程中遇到的常见问题与解决方案;
根据实际情景选择更合适的工具完成高效的设计方案
学习分享团队:
学而思培优-运营研发团队
Java并发编程分享小组:
@沈健 @曹伟伟 @张俊勇 @田新文 @张晨
本章分享人:@张晨
学习分享大纲:
01初识并发
什么是并发,什么是并行?
用个JVM的例子来讲解,在垃圾回收器做并发标记的时候,这个时候JVM不仅可以做垃圾标记,还可以处理程序的一些需求,这个叫并发。在做垃圾回收时,JVM多个线程同时做回收,这叫并行。
02为什么要学习并发编程
直观原因
1)JD的强制性要求
随着互联网行业的飞速发展,并发编程已经成为非常热门的领域,也是各大企业服务端岗位招聘的必备技能。
2)从小牛通往大牛的必经之路
架构师是软件开发团队中非常重要的角色,成为一名架构师是许多搞技术人奋斗的目标,衡量一个架构师的能力指标就是设计出一套解决高并发的系统,由此可见高并发技术的重要性,而并发编程是底层的基础。无论游戏还是互联网行业,无论软件开发还是大型网站,都对高并发技术人才存在巨大需求,因此,为了工作为了提升自己,学习高并发技术刻不容缓。
3)面试过程中极容易踩坑
面试的时候为了考察对并发编程的掌握情况,经常会考察并发安全相关的知识和线程交互的知识。例如在并发情况下如何实现一个线程安全的单例模式,如何完成两个线程中的功能交互执行。
以下是使用双检索实现一个线程安全的单例懒汉模式,当然也可以使用枚举或者单例饿汉模式。 private static volatile Singleton singleton;
private Singleton(){};
public Singleton getSingleton(){
if(null == singleton){
synchronized(Singleton.class){
if(null == singleton){
singleton = new Singleton();
}
}
}
return singleton;
}
在这里第一层空判断是为了减少锁控制的粒度,使用volatile修饰是因为在jvm中new Singleton()会出现指令重排,volatile避免happens before,避免空指针的问题。从一个线程安全的单例模式可以引申出很多,volatile和synchronized的实现原理,JMM模型,MESI协议,指令重排,关于JMM模型后序会给出更详细的图解。
除了线程安全问题,还会考察线程间的交互。 例如使用两个线程交替打印出A1B2C3…Z26
考察的重点并不是要简单的实现这个功能,通过此面试题,可以考察知识的整体掌握情况,多种方案实现,可以使用Atomicinteger、ReentrantLock、CountDownLat ch。下图是使用LockSupport控制两个线程交替打印的示例,LockSupport内部实现的原理是使用UNSAFE控制一个信号量在0和1之间变动,从而可以控制两个线程的交替打印。
4)并发在我们工作使用的框架中处处可见,tom cat,netty,jvm,Disruptor
熟悉JAVA并发编程基础是掌握这些框架底层知识的基石,这里简单介绍下高并发框架Disruptor的底层实现原理,做一个勾勒的作用:
Martin Fowler在一篇LMAX文章中介绍,这一个高性能异步处理框架,其单线程一秒的吞吐量可达六百万
Disruptor核心概念
Disruptor特征
-
基于事件驱动
-
基于"观察者"模式、"生产者-消费者"模型
-
可以在无锁的情况下实现网络的队列操作
RingBuffer执行流程
Disruptor底层组件,R