jdk1.7-ConcurrentHashMap

本文介绍了JDK1.7的ConcurrentHashMap,重点讲解了其数据结构、Unsafe类的使用,包括arrayBaseOffset、arrayIndexScale等方法,以及put和get操作的实现细节,如segment数组、HashEntry结构和分段锁策略,展示了其高并发性能的设计思想。
摘要由CSDN通过智能技术生成

1. 前言

ConcurrentHashMap是一种支持多线程的hashmap, 相对于hashTable它使用了分段锁的方式加锁, 大大提升了并发的性能

1.1. 数据结构

ConcurrentHashMaphashmap有所不同的是最初初始化的数组的每一个节点中存放的都是n个数组, 这些数组中存放的才是最终存放数据的链表.

1.2. UNSAFE

UNSAFE是Java中一个底层类,包含了很多基础的操作,比如数组操作、对象操作、内存操作、CAS操作、线程(park)操作、栅栏(Fence)操作,JUC包、一些三方框架都使用Unsafe类来保证并发安全。

转载自:UNSAFE

1.2.1. arrayBaseOffset

 
public native int arrayBaseOffset(Class arrayClass);

返回数组类型的第一个元素的偏移地址(基础偏移地址)。如果arrayIndexScale方法返回的比例因子不为0,你可以通过结合基础偏移地址和比例因子访问数组的所有元素。Unsafe中已经初始化了很多类似的常量如ARRAY_BOOLEAN_BASE_OFFSET等。

1.2.2. arrayIndexScale

 
public native int arrayIndexScale(Class arrayClass);

返回数组类型的比例因子(其实就是数据中元素偏移地址的增量,因为数组中的元素的地址是连续的)。此方法不适用于数组类型为”narrow”类型的数组,”narrow”类型的数组类型使用此方法会返回0(这里narrow应该是狭义的意思,但是具体指哪些类型暂时不明确,笔者查了很多资料也没找到结果)。Unsafe中已经初始化了很多类似的常量如ARRAY_BOOLEAN_INDEX_SCALE等。

1.2.3. objectFieldOffset

 
public native int objectFieldOffset(Class arrayClass);

返回给定的非静态属性在它的类的存储分配中的位置(偏移地址)。不要在这个偏移量上执行任何类型的算术运算,它只是一个被传递给不安全的堆内存访问器的cookie。注意:这个方法仅仅针对非静态属性,使用在静态属性上会抛异常。

1.2.4. putObjectVolatile

 
/**
* obj: 包含需要修改field的对象
* offset: obj中long型field的偏移量
* value: field将被设置的新值
*/
public native void putOrderedObject(Object obj, long offset, Object value);

此方法和putObject功能类似,不过附加了’volatile’加载语义,也就是设置值的时候强制(JMM会保证获得锁到释放锁之间所有对象的状态更新都会在锁被释放之后)更新到主存,从而保证这些变更对其他线程是可见的。类似的方法有putIntVolatile、putDoubleVolatile等等。这个方法要求被使用的属性被volatile修饰,否则功能和putObject方法相同。

1.2.5. putOrderedObject

 
/**
* obj: 包含需要修改field的对象
* offset: obj中long型field的偏移量
* value: field将被设置的新值
*/
public native void putOrderedObject(Object obj, long offset, Object value);

设置o对象中offset偏移地址offset对应的Object型field的值为指定值x。这是一个有序或者有延迟的putObjectVolatile方法,并且不保证值的改变被其他线程立即看到。只有在field被volatile修饰并且期望被修改的时候使用才会生效。类似的方法有putOrderedIntputOrderedLong

1.2.6. putIntVolatile

 
/**
* obj: 包含需要修改field的对象
* offset: obj中long型field的偏移量
* value: field将被设置的新值
*/
public native void putIntVolatile(Object obj, long offset, int value);

设置obj对象中offset偏移地址对应的整型field的值为指定值。支持volatile store语义

1.2.7. getObject

 
/**
* obj: 包含需要去读取的field的对象
* offset: obj中long型field的偏移量
*/
public native Object getObject(Object obj, long offset);

通过给定的Java变量获取引用值。这里实际上是获取一个Java对象o中,获取偏移地址为offset的属性的值,此方法可以突破修饰符的抑制,也就是无视private、protected和default修饰符。类似的方法有getInt、getDouble等等。

1.2.8. getObjectVolatile

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值