多线程
2022-10-26 22:03:56 0 举报
java多线程体系源码分析图
作者其他创作
大纲/内容
AQS
Tail
thread=ThreadAwaitStatus=0
Node
nextWaiterr
b=1/M
Execution Units
X
偏向锁
弱引用key-3
2
1.线程A和B都进入了lock.lock();由于线程A抢到了锁,所以线程A状态是1,导致线程B没有抢到锁,所以线程B加入了AQS队列
thread=ThreadCwaitStatus=0
【对齐填充】
没有得到锁的线程
Y
thyY
Z
ThreadC
L1 Cache
授权
当计数器为0时,唤醒await()的线程
Entry对象-2
yes
抢占锁
线程B
SHARED
value-1
next
3.线程A释放锁B抢到锁
Memory
head
ThreadLocalMap
竟争
prev
value-3
L2 Cache
mark-word:对象标记字段占4个字节,用于存储一些列的标记位,比如:哈希值、轻量级锁的标记位,偏向锁标记位、分代年龄等。Klass Pointer:Class对象的类型指针,Jdk1.8默认开启指针压缩后为4字节,关闭指针压缩( -XX:-UseCompressedOops )后,长度为8字节。其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址。对象实际数据:包括对象的所有成员变量,大小由各个成员变量决定,比如:byte占1个字节8比特位、int占4个字节32比特位。对齐填充:最后这段空间补全并非必须,仅仅为了起到占位符的作用。由于HotSpot虚拟机的内存管理系统要求对象起始地址必须是8字节的整数倍,所以对象头正好是8字节的倍数。因此当对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。
AbstractQueuedSynchronizer
多线程原子性问题
成功
Thead2
TheadA
ThreadLocal local1
int a=0;function(){a=1;b=a+1;assert(b==2)false}
init?
运行时
2-1=1
Synchronized是如何实现锁的,以及锁的信息是存储在哪里? 就拿上面分析的图来说,线程A抢到锁了,线程B怎么知道当前锁被抢占了,这个地方一定会有一个标记来实现,而且这个标记一定是存储在某个地方。
线程A
await()
ThreadA
nextWaiter
thread=ThreadBwaitStatus=0
Condition线程
firstWaiter
type
Head
L3 Cache
类元信息
指令重排序 store bufferes
ThreadB
Entry对象-1
state=0改成了1exclusiveOwnerThread改成了TheadA
countDown()
hashcode
2.线程A抢到锁后执行await方法,将自己加入Condition队列
synchronized(lock)
waitStatus=0
对齐填充作用
a=0/Shared
read invalidate a
response b
b=a+1
线程T2
Entry对象-3
a=0/E
链表synchronized
偏向锁持有者线程id
7
共享资源X
thread=ThreadXwaitStatus=CONDITION
holdY
SIGNAL
thread=nullwaitStatus=SIGNAL
Croe 1
waitStatus=SIGNAL
value-2
1
public synchronized void incr(){i++;}
condition.await
弱引用key-1
死锁
释放锁
isShared()?doReleseShared
new lock()
Thread1
tail
cpu1
Croe 0
指向的引用对象
TheadB
5
lastWaiter
thread=ThreadAwaitStatus=CONDITION
b=0/E
是
Registers
AQS队列
锁的特性,只能有一个线程获得,只有获得锁的线程被释放后,后续线程才有机会 获取
count=1写入内存
Thead1
yes的话调用casTabAt存数据
a=0/1
monitor()
lock.unlock()
CountDownLatch原理
ObjectMonitor争抢锁的实现逻辑
DRAM Memory
1-1=0
Markword对象头
被保护资源
markOop
store buffer
countdown
initTable
Main Thread
a=1
count=0加载到寄存器
a=0b=0
value、每个线程独占的原始数据副本
state=1exclusiveOwnerThread=ThreadA
共享资源Y
NodewaitStatus=SIGNAL
线程切换
重量级锁
CountDownLatch(3)
对象在heap中的布局
利用空间换时间防止多线程缓存行竟争问题
偏向锁设置时间:-XX:BiasedLockingStartupDelay=0
如果有多个线程,从ThreadLocal中获取对象,那么每个线程都会维护一个自己的ThreadLocalMap
exist
holdX
没有授权
分代年龄
线程T1
state=1改成了0exclusiveOwnerThread改成了null
同步锁标记
no
3-1=2
3
ThreadLocal local3
synchronized锁的实现
弱引用key-2
JUC并发工具CountDownLatch
Cache
对象头
thyX
ConcurrentHashMap
无锁
thread=nullwaitStatus=SINGAL
4
thread=BwaitStatus=0
lock.lock()
fullyRelease释放锁
ThreadLocal local2
否
Thead3
Condition队列
read invalidate b
对象标记
偏向锁开启状态
Cpu0
count++
response & invlidate ack
thread=nullwaitStatus=0
偏向锁标记
得到锁的线程
syschronized原理
state=1exclusiveOwnerThread=ThreadB
处于锁阻塞状态
Main线程调用await方法后,会导致Main线程阻塞
唤醒阻塞的线程(head.next)
实例数据
轻量级锁
ThreadLocal原理
开始
lock()方法阻塞机制
0 条评论
回复 删除
下一页