重排序、hb、ConcurrentHashMap弱一致性(jdk1.6)

时间:2022-08-29 16:49:41
double pi  = 3.14;    //A
double r   = 1.0;     //B
double area = pi * r * r; //C

1、A -> B    //不满足happens- before,不会改变程序执行结果

2、B -> C   //happens- before, 会改变程序执行结果

3、A -> C   //happens- before, 会改变程序执行结果

JMM会对1进行重排序,2、3不会;

 

 在一个线程内,

按照代码顺序,同个字段,书写在前面的操作先行发生于书写在后面的操作

在多线程并发中:

对一个monitor的解锁操作happens-before后续对同一个monitor的加锁操作”、

“对某个volatile字段的写操作happens-before后续对同一个volatile字段的读操作

 

ConcurrentHashMap

Segment里有两个volatile变量:counttable;HashEntry里有一个volatile变量:value

get方法弱一致性

含义:往ConcurrentHashMap底层数据结构中加入一个元素后,不能立马对get可见。换句话说,put操作将一个元素加入到底层数据结构后,get可能在某段时间内还看不到这个元素;

因为get方法未加锁,get方法可能会在put方法的执行过程中被调用,这就是get操作是弱一致的根本原因;

重排序、hb、ConcurrentHashMap弱一致性(jdk1.6)

另外,在put方法调用结束的时候,get方法一定能获取到值,这是如何保证的呢,因为有一个volatile修饰的变量count的存在,put结束的时候,会写入count,get开始的时候会读取count,这里存在happens- before关系

(对某个volatile字段的写操作happens-before后续对同一个volatile字段的读操作);

但是,因为get方法未加锁,所以不能保证在put方法调用结束的时候调用get,可能在中间时刻调用(即使put方法已经赋值完成),导致不存在happens- before关系,可能会因为指令重排等原因不能及时得到值;

迭代器弱一致性表现

在遍历过程中,如果已经遍历的数组上的内容变化了,迭代器不会抛出ConcurrentModificationException异常。

因为未加锁,如果未遍历的数组上的内容发生了变化,则有可能反映到迭代过程中,与get类似;