Java锁机制学习--hotspot源码查看并发同步原语设计机制
一、并发同步原语设计机制
同时开启两个线程,对A的实例对象a的一个字段进行加10000000操作,但是出现操作覆盖问题,对结果造成影响。
于是有个锁的出现。
思考:这个锁的是什么。
锁的是堆内存的当前实例对象。
二、JDK1.6之前的锁底层加锁原理
monitor+没加锁成功进入等待队列---->有忧患:线程阻塞、上下文切换、操作系统线程调度、内核态到用户态。---->如何优化。
优化;AI对象下的int value值,是volatile修饰的,默认0。时间提高了1倍多。
底层是CAS的思想。实现大致逻辑:
为什么能优化。原因:线程不存在阻塞,如果没执行成功会执行while,重试一下。所以所有线程一直都是在运行的,没有发生运行到阻塞态的频繁耗性能的操作。
1.原子性底层实现:
native方法-->c++方法-->汇编语言lock指令
compareAndSet底层是由native方法修饰的一个方法,由它(Atomic::cmpxchag)会调到汇编语言的实现。
int mp = os::is_MP:调用操作系统内核的指令函数,计算是否为多核处理器。
LOCK_IF_MP(mp):其中MP指mutiprocess(多个处理器),会返回一个lock指令(lock上cmpxchgq)。并且执行。
然后比较并交换期望的值,和你比较的值。
所以原子性问题解决:lock cmpxchgq()
对缓存行加锁,或者缓存行占的比较大,超过64字节的话,直接加总线锁。因为硬件级别只能针对一个缓存行加锁,如果放的值跨几个缓存行的话,直接在总线上加锁。各个线程都是通过总线交换数据,如果锁了缓存行,其他线程就得等着。
2.ABA问题:通过比较version字段。每次操作都改变version,可以像唯一标识记录每次操作。