Java并发
2020-08-20 09:27:22 0 举报
AI智能生成
Java虚拟机
作者其他创作
大纲/内容
锁
临界资源
解决方案
Lock和Synchroized
区别
AQS
特性
可中断
可重入
公平/非公平
共享/独占
阻塞等待队列
三板斧
state
访问方式
getState()
setState()
compareAndSetState()
队列
同步队列
条件队列
Node(节点)
模式
独占(EXCLUSIVE)
共享(SHARED)
状态
CANCELLED(1)
DEFAULT(0)
SIGNAL(-1)
CONDITION(-2)
PROPAGATE(-3)
CAS
衍生物
ReentrantLock
源码解析
ReentrantReadWriteLock
Semaphore
源码解析
CountDownLatch
CyclicBarrier
自定义同步器
isHeldExclusively()
tryAcquire(int)
tryRelease(int)
tryAcquireShared(int)
tryReleaseShared(int)
synchronized
加锁方式
实例方法
类方法
同步代码块
底层原理
Monitor对象(管程)
对像头
成员属性(部分)
_count
_owner
_WaitSet
_EntryList
访问步骤
1.获取锁
2.调用wait方法(不一定有)
3.释放锁
字节码层面
wait/notify
代码块加锁
monitorentry
monitorexit
方法签名加锁
锁优化
锁粗化
锁消除
锁升级
偏向锁
轻量级锁
自旋锁
自适应自旋锁
重量级锁
MESI
由来
总线加锁
CPU高速缓存
存在的意义
局部性原理
时间局部性
空间局部性
计算流程
1. 程序以及数据被加载到主内存
2. 数据和指令被加载到CPU的高速缓存里
3. CPU执行指令,把数据写回到高速缓存里
4. 高速缓存中的数据写回到主内存
缓存一致性协议
位置
M(修改)
E(独占)
S(共享)
I(失效)
伪共享
解决方案
@sun.misc.Contended
手动在变量附近填充无用数据
线程池原理
ThreadPoolExecutor
种类
newCachedThreadPool
newFixedThreadPool
newSingleThreadExecutor
newScheduledThreadPool
核心
提交流程
拒绝策略
AbortPolicy
CallerRunsPolicy
DiscardOldestPolicy
DiscardPolicy
线程复用
Unsafe
冯诺伊曼计算机
计算机五大核心
控制器
运算器
存储器
输入
输出
CPU
CPU指令结构
控制单元
运算单元
数据单元
具体化
CPU缓存结构
三级缓存
CPU读取存储器的过程
CPU要取寄存器的值,只需要一步:直接读取
CPU要读取L1 cache的某个值,需要1-3步(或者更多):把cache行锁住,把某个数据拿来,解锁,如果没锁住就慢了
CPU要读取L2 cache的某个值,先要到L1 cache中取,如果L1当中不存在,再去L2中取:L2开始加锁,成功后将数据复制到L1,再执行第二步的三步,再解锁
CPU取L3 cache的也一样,只不过先由L3复制到L2,再从L2复制到L1,再从L1到CPU
CPU取内存则最为复杂:通知内存控制器占用总线带宽,通知内存加锁,发起内存读取请求,等待回应,回应数据保存到L3->L2->L1->CPU,之后接触总线锁定
具体化
高速缓存必要性
局部性原理
时间局部性
空间局部性
CPU指令计算过程
取指令
指令译码
执行指令
访问取数
结果写回
CPU运行安全级别
Ring0
Ring1
Ring2
Ring3
上下文切换
模式切换
中断
子主题
内存
执行空间保护
内核线程模型(KLT)
用户线程模型(ULT)
进程与线程
进程
线程
虚拟机指令集架构
栈指令集架构
设计和实现更简单,适用于资源受限的系统
避开了寄存器的分配难题:使用零地址指令方式分配
指令流中的指令大部分是零地址指令,其执行过程依赖于操作数栈,指令集更小,编译容易实现
不需要硬件支持,可移植性更好,更好实现跨平台。
寄存器指令集架构
典型的应用是x86的二进制指令集:比如传统的PC以及Android的Davlik虚拟机。
指令集架构则完全依赖硬件,可移植性差。
性能优秀和执行更高效。
花费更少的指令去完成一项操作。
在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主。
JMM
JMM和JVM的区别
内存
主内存
工作内存
JMM与硬件内存架构的关系
不同点:硬件只有寄存器、缓存内存和主内存的概念,并没有工作内存和主内存之分
必要性
八大原子操作
lock
read
load
use
assign
store
write
unlock
具体化
八大原子操作同步规则
不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步回主内存
一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或者assign)的变量。即就是对一个变量实施use和store操作之前,必须先自行assign和load操作。
一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现。
如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎是用这个变量之前需要重新执行load或assign操作初始化变量的值
如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。
对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)
三大核心
原子性
实现
有序性
指令重排
as-if-serial
可见性
实现
Happens Before
程序顺序规则
管程锁规则
volatile规则
线程启动规则
传递性
线程终止规则
线程中断规则
对象终结规则
volatile
内存语义
保证被volatile修饰的共享变量对所有线程总是可见的,也就是当一个线程修改了一个被volatile修饰的共享变量的值,新的值总是可以被其他线程立即得知
禁止指令重排序优化
可见性
无法保证原子性
禁止重排优化
硬件层内存屏障
lfence,是一种Load Barrier读屏障
sfence,是一种Store Barrier写屏障
mfence,是一种全能型屏障,拥有lfence和sfence的能力
locak前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线,和高速缓存加锁,可以理解为CPU指令级的一种锁。
JVM内存屏障
指令
LoadLoad
StoreStore
StoreLoad
LoadStore
作用
保证特定操作的执行顺序
保证某些变量的内存可见性
重排规则
当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后
当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前
当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。
JMM插入策略
在每个volatile写操作的前面插入一个StoreStore屏障
在每个volatile写操作的后面插入一个StoreLoad屏障
在每个volatile读操作的后面插入一个LoadLoad屏障
在每个volatile读操作的后面插入一个LodStore屏障
Atomic
基本类型
AtomicInteger
AtomicLong
AtomicBoolean
引用类型
AtomicReference
AtomicReferenceFieldUpdater
AtomicMarkableReference
数组类型
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray
属性原子修改器
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicStampedUpdater
ThreadLocal
0 条评论
下一页