Java分布式应用学习笔记04JDK的并发包的集合总结---前篇
public V put(K key, V value) { if (value == null) throw new NullPointerException(); int hash = hash(key.hashCode()); return segmentFor(hash).put(key, hash, value, false); }
?首先判断值是否为空,空值不必要存储,之后根据key的哈希值计算一个hash值。根据计算出的hash值去获取segment对象。找到了segment对象后调用该对象的put方法完成操作。Segment是ConcurrentHashMap的内部类其底层原理使用一个transient volatile HashEntry<K,V>[] table;进行存取。现在再看segment内的put源码
V put(K key, int hash, V value, boolean onlyIfAbsent) { lock(); try { int c = count; if (c++ > threshold) // ensure capacity rehash(); HashEntry<K,V>[] tab = table; int index = hash & (tab.length - 1); HashEntry<K,V> first = tab[index]; HashEntry<K,V> e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) e = e.next; V oldValue; if (e != null) { oldValue = e.value; if (!onlyIfAbsent) e.value = value; } else { oldValue = null; ++modCount; tab[index] = new HashEntry<K,V>(key, hash, first, value); count = c; // write-volatile } return oldValue; } finally { unlock(); } }?首先是进行加锁操作,之后就是进行数组大小的判断,如果容量不够,则需要扩充。之后再通过对hash值的按位与的操作后,得到了这个key所要放置的位置。有了位置了,再看HashEntry数组组成的对象链,是否已经有key,如果有了,覆盖value操作,如果没有,创建一个新的HashEntry对象,重新组成HashEntry链表,最后进行解锁操作。
V readValueUnderLock(HashEntry<K,V> e) { lock(); try { return e.value; } finally { unlock(); } }
?下面我们来看看性能,在此所说的性能仅仅指时间执行效率。
package threadConcurrent.hashMap;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** @author liuyan * */public class PubHashMap implements Runnable {final static int ThreadSIZE = 2500;final static int elSize = 500;int threadNum;public PubHashMap(int threadNum) {this.threadNum = threadNum;}@Overridepublic void run() {Map<String, String> hashMap = new HashMap<String, String>();for (int i = 0; i < elSize; i++) {hashMap.put(i + "" + threadNum, i + "" + threadNum);}}/** * @param args */public static void main(String[] args) {// 启用线程池ExecutorService exec = Executors.newFixedThreadPool(ThreadSIZE);long startTime = System.currentTimeMillis();for (int index = 0; index <= ThreadSIZE; index++) {exec.execute(new PubHashMap(index));}long endTime = System.currentTimeMillis();exec.shutdown();System.out.println("消耗时间:" + (endTime - startTime) + "ms");}}
消耗时间:1753ms
package threadConcurrent.hashMap;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** @author liuyan * */public class PutConcurrentHashMap implements Runnable {final static int ThreadSIZE = 2500;final static int elSize = 500;int threadNum;public PutConcurrentHashMap(int threadNum) {this.threadNum = threadNum;}@Overridepublic void run() {Map<String, String> concurrentHashMap = new ConcurrentHashMap<String, String>();for (int i = 0; i < elSize; i++) {concurrentHashMap.put(i + "" + threadNum, i + "" + threadNum);}}/** * @param args */public static void main(String[] args) {// 启用线程池ExecutorService exec = Executors.newFixedThreadPool(ThreadSIZE);long startTime = System.currentTimeMillis();for (int index = 0; index <= ThreadSIZE; index++) {exec.execute(new PutConcurrentHashMap(index));}long endTime = System.currentTimeMillis();exec.shutdown();System.out.println("消耗时间:" + (endTime - startTime) + "ms");}}
消耗时间:1869ms
public boolean add(E e) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len + 1);newElements[len] = e;setArray(newElements);return true;} finally {lock.unlock();}}
public E remove(int index) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;Object oldValue = elements[index];int numMoved = len - index - 1;if (numMoved == 0)setArray(Arrays.copyOf(elements, len - 1));else {Object[] newElements = new Object[len - 1];System.arraycopy(elements, 0, newElements, 0, index);System.arraycopy(elements, index + 1, newElements, index,numMoved);setArray(newElements);}return (E) oldValue;} finally {lock.unlock();}}
楼主这还不算深入?看来我可以洗洗睡了 楼主这还不算深入?看来我可以洗洗睡了