JAVA并发容器源码分析【二】ConcurrentHashMap分析之replaceNode
replaceNode方法
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495/** * Implementation for the four public remove/replace methods: * Replaces node value with v, conditional upon match of cv if * non-null. If resulting value is null, delete. * 删除/替换的操作 * */ final V replaceNode(Object key, V value, Object cv) { //发散hash int hash = sp ...
JAVA并发容器源码分析【二】ConcurrentHashMap分析之putVal
基于JDK8的ConcurrentHashMap中的putVal源码及注释:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495/** Implementation for put and putIfAbsent * 实现put和putIfAbsent * onlyIfAbsent含义:如果我们传入的key已存在我们是否去替换,true:不替换,false:替换。 * */ final V putVal(K key, V value, boolean onlyIfAbsent) { //键值都不为空 if (key == null || value == null) throw new NullPointerExceptio ...
JAVA并发容器源码分析【二】ConcurrentHashMap分析之get
先贴一段代码,根据源码分析ConcurrentHashMap中的get方法:
12345678910111213141516171819202122232425262728293031323334353637383940414243/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * * 返回指定键映射到的值,如果此映射不包含键的映射,则返回{@code null}。 * * <p>More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code key.equals(k)}, * then this method returns & ...
JAVA并发容器源码分析【二】ConcurrentHashMap分析之tabAt-casTabAt-setTabAt
引言ConcurrentHashMap中有大量的CAS操作,tabAt、casTabAt、setTabAt是用来实现CAS的方法。在这只是简单的学习了解,不做深层次的学习,比如为啥用sun.misc.Unsafe,绕过JVM优化数组操作之类的。
tabAt获取数组tab中索引为i的节点。
1234static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { //native 方法 获取当前节点 return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); }
casTabAt用CAS方法设置数组tab中索引为i的节点的值,如果当前节点与期望的节点c相同,则更新为节点v。
12345static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, ...
JAVA并发容器源码分析【二】ConcurrentHashMap分析之数据结构(JDK7与JDK8)
引言ConcurrentHashMap的数据结构奠定了其高并发编程中的作用。其基本的数据结构还是离不开其本源HashMap。比如JDK8中他们同样用了数组+链表+红黑树,只不过在ConcurrentHashMap中增加了一些无锁技术,来实现多线程操作容器。
JDK7先贴两张盗的图(实在不想画图,就找了两张喜欢的)从图中可以看出,其数据结构主要由Segment数组+HashEntry数组+链表组成,也就是说定位一个数据时,要通过两次Hash计算。
JDK7的ConcurrentHashMap主要通过锁分段技术实现对资源的并发访问。Segment数组中的每个Segment,都是继承自ReentrantLock (可重入锁,后期再写一个锁的专题),即其锁的粒度为Segment。
在一个线成获取到这个Segment的锁的时候,其他线成可以访问别的Segment,以此增加了容器处理的吞吐量。
JDK8JDK8的HashMap中比JDK7多了一个红黑树以用来增加数据分布的平衡性。JDK8的ConcurrentHashMap相对于JDK7来说,锁的粒度变小了,也就是说并发性更大了。用了synchro ...
JAVA并发容器源码分析【二】ConcurrentHashMap分析之CAS原理
锁的产生锁,是为了解决并行运算时,数据并发读写的安全性问题。
锁的分类在实现锁的技术中,分为乐观锁与悲观锁,悲观锁总是假设坏的情况,认为同一份数据在并发情况下一定会有修改,而乐观锁则相反,认为那份数据不会发生修改,在更新数据时会采用尝试不断重试的方式更新数据。
JAVA中的各种锁都是悲观锁,乐观锁是通过CAS技术实现。
CASCAS(Compare And Swap,比较交换):多个线程尝试使用CAS同时更新同一份数据时,只有其中一个线程能更新数据的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以重复尝试修改数据的值。CAS 操作中包含三个操作数 —— 需要读写的内存位置(V)、进行比较的预期原值(A)和拟写入的新值(B)。如果内存位置V的值与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B。否则处理器不做任何操作。
Java中的CASJava中CAS操作通过JNI本地方法实现:
1unsafe.compareAndSwapInt(this, valueOffset, expect, update)
CAS的缺点1. ABA问题
你拿着一个装满钱的 ...
JAVA并发容器源码分析【二】ConcurrentHashMap源码翻译之核心方法
基于JDK8
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002 ...
JAVA并发容器源码分析【二】ConcurrentHashMap源码翻译之基础
基于JDK8
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002 ...
JAVA并发容器源码分析【四】LinkedBlockingQueue介绍
特点
是先进先出队列FIFO。
采用ReentrantLock保证线程安全
功能增加增加有三种方式,前提:队列满
方式
put
add
offer
特点
一直阻塞
抛异常
返回false
删除删除有三种方式,前提:队列为空
方式
remove
poll
take
特点
NoSuchElementException
返回false
阻塞
JAVA并发容器源码分析【二】ConcurrentHashMap源码翻译之类注释与综述部分
JDK8源码,ConcurrentHashMap的类注释与综述部分:
类注释123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 ...