一:HashMap
--->底层存储的是Entry<K,V>[]数组
--->Entry<K,V>的结构是一个单向的链表
static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;

/**
         * Creates new entry.
         */
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
}

--->存储或移除的定位。
 (1)存储key的时候,先取key的hascode,然后对hascode进行一系列的按位与,按位异或运算最终得到一个数字,再拿这个数字和Entry[]数组的长度减一进行按位与运算,求出要存储的数组下标。
(2)拿到数组上的entry对象,然后遍历,对key的hashcode比较。如果hashcode相同,再进行equals比较内容。如果都相同,则表示是同一个key,则进行替换。如果没有相等的,则new一个entry对象,加到链表的末尾。
(3)如果拿对象作为key的话。一定要重写这个对象的hashcode方法和equals方法。确保存储和查找正常。
(4)不同的对象hascode可能会相同,因此一定要重写equals方法。

二:ConcurrentHashMap
--->底层是一个Segment<K,V>[]数组。先对key进行hash运算,得到segment数组的下标,然后将数据存放到segment对象内部的HashEntry数组中去。这个存放和hasMap就一致了。
--->Segment<K,V>对象又是继承重入锁的ReentrantLock的对象。
--->每个Segment元素内部又存储了一个HashEntry<K,V>[]数组
--->将来每个key-value对是转化成HashEntry对象。
--->HashEntry的结构又是单向链表结构
--->该类利用了Unsafe类提供的cas操作和线程锁的方法。实现线程安全和高效。所谓的分段锁技术,就是将元素存储在多个容器中,每个容器都有自己的一把锁。将单个锁的压力分摊给多个锁。大大减少了互斥的发生。又因为没有使用synchronized的重量级锁。使用的是并发包的锁机制。而并发包的锁机制,依赖的是jdk的unsafe类提供的原子操作,和线程阻塞技术实现的同步。
--->存的时候使用了锁。
--->读的时候利用的unsafe提供的voliate语意直接读取内存的方法。
static final class HashEntry<K,V> {
        final int hash;
        final K key;
        volatile V value;
        volatile HashEntry<K,V> next;

HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
}

java多线程:并发包中ConcurrentHashMap和jdk的HashMap的对比的更多相关文章

  1. Java多线程_并发容器ConcurrentHashMap/CopyOnWriteArrayList/CopyOnWriteArraySet

    ConcurrentHashMap         HashMap是线程不安全的,可以使用Collections.synchronizedMap(map)把一个不安全的map变成安全的,但是这里可以直 ...

  2. Java 多线程查找文件中的内容

    学过了操作系统,突然不知道多线程有什么用了. 看了一下百度,发现多线程,可以提升系统利用率 在系统进行IO操作的时候,CPU可以处理一些其他的东西,等IO读取到内存后,CPU再处理之前的操作. 总之可 ...

  3. java多线程向数据库中加载数据

    读取本地文件,每行为一条记录,文件大小550M,200万条数据.先将文件读取的内存中,再开启6个线程连接postgresql不同coordinator端口导入数据.代码如下: import java. ...

  4. java 多线程 2 Thread中start()和run()的区别

  5. java多线程并发编程中的锁

    synchronized: https://www.cnblogs.com/dolphin0520/p/3923737.html Lock:https://www.cnblogs.com/dolphi ...

  6. Java并发包中Semaphore的工作原理、源码分析及使用示例

    1. 信号量Semaphore的介绍 我们以一个停车场运作为例来说明信号量的作用.假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了三辆车,看门人允许其中它们进入进入,然后放下车拦.以后 ...

  7. Java多线程(四)java中的Sleep方法

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  8. java 多线程总结篇4——锁机制

    在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...

  9. Java多线程并发05——那么多的锁你都了解了吗

    在多线程或高并发情境中,经常会为了保证数据一致性,而引入锁机制,本文将为各位带来有关锁的基本概念讲解.关注我的公众号「Java面典」了解更多 Java 相关知识点. 根据锁的各种特性,可将锁分为以下几 ...

随机推荐

  1. IOS 中的KVO模式 观察者模式

    / // KvoObject.h // KVO // // Created by lin kang on 16/6/7. // Copyright © 2016年 lin kang. All righ ...

  2. hdu 1950 最长上升子序列

    //Accepted 3540 KB 62 ms //dp 最长上升子序列 #include <cstdio> #include <cstring> #include < ...

  3. SQL Server 按某一字段分组 取 最大 (小)值所在行的数据

    SQL Server 按某一字段分组 取 最大 (小)值所在行的数据 -- 按某一字段分组 取 最大 (小)值所在行的数据 -- (爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23 ...

  4. ISO c++11 does not allow conversion from string literal to 'char*'

    http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char

  5. 算法----Magic Index

    给定一个数组 A,如果 某个下标 i, 满足 A[i] = i, 则 i 称为 Magic Index. 现在假设 A 中的元素是递增有序的.且不重复,找出 Magic Index. 更进一步,当数组 ...

  6. yii2.0-rules验证规则应用实例

    Rules验证规则:  required : 必须值验证属性||CRequiredValidator 的别名, 确保了特性不为空. [['字段名1','字段名2'],required]    //字段 ...

  7. 【LeetCode】Best Time to Buy and Sell Stock IV

    Best Time to Buy and Sell Stock IV Say you have an array for which the ith element is the price of a ...

  8. WinFrm窗体的传值方式

    比较简单的方法: 一:1.定义两个窗体 2.在父窗体中加入子窗体的属性 public ChildFrm ChildFrm { get; set; } 3.加载的时候: private void Par ...

  9. Unity3D ShaderLab立方体图的法线渲染

    Unity3D ShaderLab立方体图的法线渲染 某些情况下,我们希望立方体图的材质球上产生法线效果,来更多的表现细节,比如菱形花纹的玻璃,冰块的表面. 在帧数的协调下,我们可以通过input结构 ...

  10. 用C语言计算圆的面积~!!!!!!!

    #include <stdio.h>void main(){ int a,b,c,y,g,f; printf("圆柱底面的半径,圆柱的高"); scanf(" ...