java多线程:并发包中ConcurrentHashMap和jdk的HashMap的对比

一: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;
        }
}

时间: 2024-09-25 04:37:57

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

Java多线程同步设计中使用Metux

Mutex是互斥体,广泛地应用在多线程编程中.本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨.在Doug Lea的concurrent工具包中,Mutex实现了Sync接口,该接口是concurrent工具包中所有锁(lock).门(gate)和条件变量(condition)的公共接口,Sync的实现类主要有:Mutex.Semaphore及其子类.Latch.CountDown.ReentrantLock等.这也体现了面向抽象编程的思想,使我们可

java多线程:jdk并发包的总结(转载)

转载地址:http://blog.csdn.net/yangbutao/article/details/8479520 1.java 高并发包所采用的几个机制(CAS,volatile,抽象队列同步)    CAS(乐观操作),jdk5以前采用synchronized,对共享区域进行同步操作,synchronized是重的操作,在高并发情况下,会引起线程频繁切换:而CAS是一种乐观锁机制,compare and swap,不加锁,而是假设没有冲突去完成,若有冲突会重试(非阻塞).compare&

Java 中ConcurrentHashMap的实现_java

ConcurrentHashMap(简称CHM)是在Java 1.5作为Hashtable的替代选择新引入的,是concurrent包的重要成员.在Java 1.5之前,如果想要实现一个可以在多线程和并发的程序中安全使用的Map,只能在HashTable和synchronized Map中选择,因为HashMap并不是线程安全的.但再引入了CHM之后,我们有了更好的选择.CHM不但是线程安全的,而且比HashTable和synchronizedMap的性能要好.相对于HashTable和sync

从ConcurrentHashMap的演进看Java多线程核心技术

线程不安全的HashMap众所周知,HashMap是非线程安全的.而HashMap的线程不安全主要体现在resize时的死循环及使用迭代器时的fast-fail上. 注:本章的代码均基于JDK 1.7.0_67 HashMap工作原理HashMap数据结构常用的底层数据结构主要有数组和链表.数组存储区间连续,占用内存较多,寻址容易,插入和删除困难.链表存储区间离散,占用内存较少,寻址困难,插入和删除容易. HashMap要实现的是哈希表的效果,尽量实现O(1)级别的增删改查.它的具体实现则是同时

简介Java多线程在交易中间件测试中的应用

引言 随着信息系统的结构的日益复杂和规模的不断扩大,交易中间件在复杂系统的应用也越来越广.交易中间件 作为一个中间层的系统,在接收客户端请求时,通常需要做一些负载控制和用户缓存的一些功能.对于软件测试人员来说, 测试交易中间件时,避免不了模拟客户端在高负载情况下的一些有规律或随机的行为.这些测试有时是功能性验证测试 (Functional Verification Test),有时也涉及到性能测试 (Performance Test). 本文将介绍如何使用 Java 语言 编写多线程的自动化测试

java多线程和并发包入门示例_java

一.java多线程基本入门java多线程编程还是比较重要的,在实际业务开发中经常要遇到这个问题. java多线程,传统创建线程的方式有两种. 1.继承自Thread类,覆写run方法. 2.实现Runnable接口,实现run方法. 启动线程的方法都是调用start方法,真正执行调用的是run方法.参考代码如下: 复制代码 代码如下: package com.jack.thread; /** * 线程简单演示例子程序 *  * @author pinefantasy * @since 2013-

关于java多线程中的join方法

问题描述 关于java多线程中的join方法 1.主线程可能在子线程结束之前 结束吗?如果可能的话 举一个例子 2.如何理解join方法, 结合实际应用. 非常感谢非常感谢!!! 解决方案 关于join,参考:http://www.blogjava.net/jnbzwm/articles/330549.html 解决方案二: 主线程可能在子线程结束之前 结束吗 一般来说不可以,但是也不一定,如果子线程在执行finally中的代码,应该会等它执行完了才退出. 晕,join方法和什么"让主线程等子线

Java多线程同步中的两个特殊类

Java语言内置了synchronized关键字用于对多线程进行同步,大大方便了Java中多线程程序的编写.但是仅仅使用synchronized关键字还不能满足对多线程进行同步的所有需要.大家知道,synchronized仅仅能够对方法或者代码块进行同步,如果我们一个应用需要跨越多个方法进行同步,synchroinzed就不能胜任了.在C++中有很多同步机制,比如信号量.互斥体.临届区等.在Java中也可以在synchronized语言特性的基础上,在更高层次构建这样的同步工具,以方便我们的使用

Java多线程编程中synchronized线程同步的教程_java

0.关于线程同步 (1)为什么需要同步多线程?线程的同步是指让多个运行的线程在一起良好地协作,达到让多线程按要求合理地占用释放资源.我们采用Java中的同步代码块和同步方法达到这样的目的.比如这样的解决多线程无固定序执行的问题: public class TwoThreadTest { public static void main(String[] args) { Thread th1= new MyThread1(); Thread th2= new MyThread2(); th1.sta