多线程进阶=>高并发JUC学习笔记
一、什么是JUC?
二、线程与进程
①基础
②线程状态State
③并发与并行
并发编程本质:充分利用CPU资源
④wait与sleep区别
三、Lock锁
①传统Synchronized方法
②Lock锁
③Synchronized与Lock的区别
④各种锁
1.(非)公平锁
公平锁:非常公平,不能够插队,必须先来后到!
非公平锁:非常不公平,可以插队[默认是非公平锁]
2.可重入锁(递归锁)
(1)Synchronized版本
(2)Lock版
3.死锁
就不做过多介绍,这里截图在多线程的例子
4.自旋锁[自定义锁]
运行结果:
B进程必须等待A进程Unlock后,才能Unlock,在这之前进行自旋等待。。。。
5.死锁排查
面试,工作中! 排查问题:
1、日志 9 成
2、堆栈 1成
四、生产者和消费者问题
1.Synchronized版本
2.Lock版
然后如何做到准确通知和唤醒?而不是随机=>
五、8锁现象【8个锁的问题】
六、集合类不安全
1.List不安全
①Vector底层是使用synchronized关键字来实现的:效率特别低下。
②Collections.synchronizedList是利用给所有的方法加了锁 转换集合[方案二] 不过太简单粗暴,降低并发量
③CopyOnWriteArrayList()写时不复制,写时再去复制【底层用了violidate和transient】
2.Set不安全
new HashSet底层原理,实际上是HashMap
例子
3.Map不安全
new HashMap底层
例子
解决方案
4.阻塞队列下一章会讲解使用
七、阻塞队列
1.概念定义
2.为何要使用?
3.如何学会使用队列
操作是添加、删除
实际要学的是一下四组API
①添加:add 移除:remove =>抛出异常
②添加:offer 移除:poll =>无返回值,不跑出异常
③添加:put 移除:take =>等待
④添加:offer 移除:poll =>超时等待
4.SynchronizedQueue同步队列
八、Callable
1.源码分析
①首先Thread
看出 只能传入Runnalbe的参数
②看看Runnable的实现类FutureTask
这样我们就可以先把Callable 放入到FutureTask中, 如何再把FutureTask 放入到Thread就可以
2.代码
九、常用辅助类
①CountDownLatch 减法计数器
②CyclickBarrier 加法计数器
③Semaphone 信号量
抢车位:3个停车位 6个车
十、读写锁
十一、线程池
线程池:三大方法、7大参数、4种拒绝策略
1.池化技术概述
2.三大方法
①方法源码
②代码
3.七种参数
代码:
4.四种拒绝策略
5.设置池的大小
十二、四大函数式接口
①Function 函数式接口
②Consumer 消费式接口
③Predicate 断定型接口
④Supplier 供给型接口
十三、Stream流式计算
大数据:存储+计算
存储:集合|MySQL
计算:交给流来操作
十四、ForkJoin
1.什么是ForkJoin?
在jdk1.7,并行执行任务!提高效率,大数据量!
大数据:Map Reduce(吧大任务拆分成小任务)
2.ForkJoin特点:工作窃取
实现原理是:双端队列!从上面和下面都可以去拿到任务进行执行!
3.如何使用ForkJoin
4.其他两种方式求和汇总
5.reduce方法
十五、异步回调
Future 设计的初衷:对将来的某个事件结果进行建模
其实就是前端 --> 发送ajax异步请求给后端,
但是我们平时都使用CompletableFuture
步骤:异步执行=>成功回调+失败回调
1.没有返回值的runAsync异步回调
2.有返回值的supply Async异步回调
十六、JMM【回顾多线程的课程即可】
十七、Volatile
Volatile 是 Java 虚拟机提供 轻量级的同步机制
1、保证可见性
2、不保证原子性
3、禁止指令重排
①保证可见性
②不保证原子性
原子性:不可分割;
线程A在执行任务的时候,不能被打扰的,也不能被分割的,要么同时成功,要么同时失败.
保证原子性:lock、synchhronized外 还有CAS
CAS:利用原子类
这些类的底层都直接和操作系统挂钩!是在内存中修改值。
③禁止指令重排
十八、深入单例模式【只要是单例 构造器一定要私有化】
①饿汉式
DLC懒汉式
需要的时候再创建,节省空间。
问题1:只能用于单线程,无法使用多线程的问题
改进=>加锁
问题2:发现new对象 不是一个原子性操作,会造成指令重排的可能
改进=> 加volatile
问题3:反射会破坏上面单例模式
改进=>在构造器加吧锁
问提4:发现单例又反射被破坏了
不用上面写的getInstance(),而是全用构造器创建对象,发现单例又被破坏了
改进=>加一个标志:红绿灯
问提5:红绿灯标记被人知道了,单例模式被反射破解
发现红绿灯标志被知道了:不管怎么写,总有人会解密知道这个
③枚举类:
点进去看下源码
新建一个枚举类
可是这边target却有写空参构造法
探究:
所以
源码
所以确实反射不能破坏枚举类
④静态内部类
十九、深入理解CAS
1.什么是CAS?
2.unsafe
①点先这个U。
getAndInt留给②去点.
②点这个getAndInt
还采用了自旋锁[do whie]
3.总结
CAS:比较当前工作内存中的值 和 主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环,使用的是自旋锁。
缺点:
①循环会耗时;
②一次性只能保证一个共享变量的原子性;
③它会存在ABA问题
4.ABA
二十、原子引用
解决ABA问题,对应的思想:就是使用了乐观锁~
带版本号的 原子操作!
总结:取自bilibli狂神
知识点复习图