Java并发编程(JUC)
2021-09-03 14:46:32 0 举报
AI智能生成
Java并发编程(JUC)
作者其他创作
大纲/内容
分支主题
Synchronized(obj)把一个对象当成锁,通过该对象的对象头数据来判断是否为该进程
第一个线程访问时:偏向锁---单纯记录线程号(没有加锁)
有线程竞争时,升级为自旋锁---等待的线程先进行自旋(默认10次) 用户态
阻塞线程自旋次数达标后拿不到锁时,升级为重量级锁,该进程进入等待状态(wait)---重量级锁需要找OS申请(经过内核态)
对象头上有两个标记位,用户记录当前的锁(锁升级)
对象头还记录当前持有锁的线程,以及进入锁次数(可重入锁的实现)
锁机制
加锁对象不能是String Integer Long等基础数据类型
程序中如果抛出异常,锁默认会释放
Synchronized
基础
如果只选时间段(加锁代码少),线程数少,则使用自旋锁
执行时间长,线程数多,用系统锁
自旋锁和系统所的选择---自旋锁消耗CPU但不经过内核态
每个线程都有自己的工作内存,会把使用到的值从共享内存复制到工作内存,线程对工作内存变量的修改不会马上同步到共享内存。加上volatile可保证每次都同步数据到主内存和其他线程,各线程之间缓存一致
实现依赖硬件的MESI协议(缓存一致性协议)
保证线程可见性
CPU执行指令可并发执行多条,为了充分利用这一点,编译器对源码进行编译完后,可对指令进行重新排序
什么是指令重排?
lfence原语指令(load | 在lfence指令前的读操作当必须在lfence指令后的读操作前完成)
sfence原语指令(store| 在sfence指令前的写操作当必须在sfence指令后的写操作前完成)
mfence原语指令(modify/mix | 在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成)
实现原理,CPU级别加了读屏障和写屏障
禁止指令重排序
Volatile
内部采用分片锁的方式,用的CAS操作
longadder
AtomicXXX
上面三种方式,计数时Atomic效率要比Synchronized高,在并发线程循环比较多时longadder比Atomic高
采用该技术的工具类:AtomicXXX类,ReentrantLock等
采用CPU级别原语指令实现,java中采用Unsafe类
V:要更改的对象
Expected:期望当前的值
NewValue:要更改的新值
影响:如果是基础类型无所谓;如果无引用类型,引起问题。
解决:加版本号--->AtmociXXX带有版本号的类
ABA问题
CAS(无锁优化 自旋锁 乐观锁)
Java并发编程(JUC)
收藏
0 条评论
回复 删除
下一页