`
异步获取爱
  • 浏览: 79944 次
  • 性别: Icon_minigender_1
  • 来自: 大男子主义世界
社区版块
存档分类
最新评论

基于HashMap的高并发Map

阅读更多
用一个Map存放常用的Object,这个Map的并发读取的频率很高,而写入的频率很低,一般只在初始化、或重新装装载的时候写入。读写冲突虽然很少发生,不过一旦发生,Map的内部结构就可能乱掉,所以,我们不得不为Map加上同步锁。
我们可以采用Copy On Write的机制,来加强Map的读取速度。
Copy On Write是这样一种机制。当我们读取共享数据的时候,直接读取,不需要同步。当我们修改数据的时候,我们就把当前数据Copy一份副本,然后在这个副本上进行修改,完成之后,再用修改后的副本,替换掉原来的数据。这种方法就叫做Copy On Write。
Oracle等关系数据库的数据修改就采用Copy On Write的模式。Copy On Write模式对并发读取的支持很好,但是在并发修改的时候,会有版本冲突的问题。可能有多个线程同时修改同一份数据,那么就同时存在多个修改副本,这多个修改副本可能会相互覆盖,导致修改丢失。因此,Oracle等数据库通常会引入版本检查机制。即增加一个版本号字段,来检测是否存在并发修改。相似的版本控制机制存在于CVS、SVN等版本控制工具中。
在我们的Copy On Write Map中,我们只需要让新数据覆盖旧数据就可以了,因此不需要考虑版本控制的问题。这就大大简化了我们的实现。
基本思路就是让读和写操作分别在不同的Map上进行,每次写完之后,再把两个Map同步。代码如下:
/*
 * Copy On Write Map
 * 
 * Write is expensive.
 * Read is fast as pure HashMap.
 *
 * Note: extra info is removed for free use
 */
import java.lang.Compiler;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import java.util.Collections;
 public class ReadWriteMap implements Map {
	protected volatile Map mapToRead = getNewMap();
 	// you can override it as new TreeMap();
	protected Map getNewMap(){
		return new HashMap();
	}
 	// copy mapToWrite to mapToRead
	protected Map copy(){
		Map newMap = getNewMap();
		newMap.putAll(mapToRead);
		return newMap;
	}
 
	// read methods
	public int size() {
		return mapToRead.size();
	}
	public boolean isEmpty() {
		return mapToRead.isEmpty();
	}
 
	public boolean containsKey(Object key) {
		return mapToRead.containsKey(key);
	}
 
	public boolean containsValue(Object value) {
		return mapToRead.containsValue(value);
	}
 
	public Collection values() {
		return mapToRead.values();
	}
 
	public Set entrySet() {
		return mapToRead.entrySet();
	}
 
	public Set keySet() {
		return mapToRead.keySet();
	}
 
	public Object get(Object key) {
		return mapToRead.get(key);
	}
 
	// write methods
	public synchronized void clear() {
		mapToRead = getNewMap();
	}
 
	public synchronized Object remove(Object key) {
		Map map = copy();
		Object o = map.remove(key);
		mapToRead = map;
		return o;
	}
 
	public synchronized Object put(Object key, Object value) {
		Map map = copy(); 
		Object o = map.put(key, value);
		mapToRead = map;
		return o;
	}
 
	public synchronized void putAll(Map t) {
		Map map = copy(); 
		map.putAll(t);
		mapToRead = map;
	}
}


这个Map读取的时候,和普通的HashMap一样快。
写的时候,先把内部Map复制一份,然后在这个备份上进行修改,改完之后,再让内部Map等于这个修改后的Map。这个方法是同步保护的,避免了同时写操作。可见,写的时候,开销相当大。尽量使用 putAll() method。
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Hashmap实现了Map接口的底层实现.docx

    HashSet是基于HashMap实现的。它内部维护了一个HashMap,用于存储实际的元素。HashSet不保证元素的顺序,且不允许有重复元素。当向HashSet添加元素时,元素实际上会被存入内部的HashMap,键是添加的元素,值是一个...

    基于共享内存的hashmap

    5. 高并发优化:在高并发环境下,如何设计数据结构和算法来最大化吞吐量和减少延迟? 在实际应用中,基于共享内存的HashMap可能用于分布式缓存、数据库连接池、进程间通信等场景,它的优点在于减少了数据复制的开销...

    Java里多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)

    在Java编程中,Map接口是用于存储键值对的数据结构,而Java提供了多种Map的实现,包括TreeMap、HashMap和ConcurrentSkipListMap。本文主要比较了这三种Map的性能,尤其是在插入和查找操作上的效率。 1. **TreeMap**...

    Java中List、ArrayList、Vector及map、HashTable、HashMap分别的区别.

    ArrayList和LinkedList虽然不是Set,但它们的父接口List属于Collection,而Collection接口有一个子接口Set,例如HashSet是Set接口的一个实现,它内部基于HashMap实现,保证元素唯一性。 7. WeakHashMap WeakHashMap...

    Java中HashMap详解(通俗易懂).doc

    HashSet是基于HashMap实现的,它不存储值,只存储键。当向HashSet添加元素时,实际上是在HashMap中添加键,而值是默认的null。由于HashSet没有值的概念,所以它不提供键值对的关联操作,仅提供基本的添加、删除和...

    深入arraylist,linkedlist,hashmap,hashset源码(2012/3/18)

    HashSet是一个不包含重复元素的集合,它基于HashMap实现。HashSet的元素添加和查找效率高,因为它依赖于HashMap的哈希功能。当我们向HashSet中添加元素时,实际上是在HashMap中存储键值对,其中键是元素本身,值是...

    Hashtable和HashMap的区别:

    相反,如果你的应用程序需要处理多线程并发问题,并且对线程安全性有严格要求,那么 `Hashtable` 或者通过 `Collections.synchronizedMap()` 包装后的 `HashMap` 更适合。了解这些区别有助于开发者在实际开发过程中...

    HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别.docx

    与HashSet的区别在于,HashSet是基于HashMap实现的集合类,用于存储唯一对象。HashSet中的元素没有顺序,添加元素时,HashSet会将元素转化为键放入HashMap中。因此,HashSet的插入和查找速度与HashMap相当,但由于...

    Map集合的继承关系图.pdf

    1. HashMap:这个类是基于散列的Map接口实现,它不保证映射的顺序。HashMap允许null值和null键。这个类不允许使用同步(synchronized),也就是说,如果没有外部同步,它不是线程安全的。 2. TreeMap:基于红黑树...

    Java魔法解密:揭秘HashMap底层机制.pptx.pptx

    这种设计允许HashMap在高并发环境中保持较高的性能。 **HashMap的存储结构** HashMap的内部结构由键值对组成的数组构成,每个键值对是一个节点,节点中包含键、值以及指向下一个节点的引用。哈希函数将键转换为数...

    Java中常用Map测试示例

    `Map`接口还有其他实现,如`TreeMap`,它基于红黑树,提供有序的键值对,`LinkedHashMap`保持插入顺序或访问顺序,`ConcurrentHashMap`则适用于多线程环境下的并发操作。 在实际应用中,选择哪种`Map`实现取决于...

    java map实例,排序

    `HashMap`的内部实现基于哈希表,通过计算键对象的哈希值来快速定位元素,因此它的插入、删除和查找操作通常具有较高的性能。 `LinkedHashMap`是另一种Map实现,它保持了元素插入的顺序,即遍历Map时,元素会按照...

    Map地图

    4. ConcurrentHashMap:线程安全,适用于多线程环境,提供了高并发性能,根据分段锁策略设计。 5. Hashtable:线程同步,与HashMap类似,但不支持null键和null值,是遗留类。 在源码分析方面,我们可以关注这些实现...

    09、并发容器(Map、List、Set)实战及其原理

    - **ConcurrentHashMap**:Java 5引入的并发容器,提供了高并发性能。它将内部划分为多个段,每个段由一个独立的锁控制,允许不同段的并发修改,提高了效率。 3. **List接口与并发容器**: - **ArrayList**和**...

    java map集合

    Java中的Map集合是一种存储键值对的数据结构,它允许我们通过键来查找对应的值,而键在Map中必须是唯一的。Map接口是Java Collections ...理解Map的工作原理以及各种实现类的特点,对于编写高质量的Java代码至关重要。

    JavaHashSet和HashMap源码剖析编程开发技术

    HashSet类是基于HashMap实现的,它不包含重复元素,并且不保证集合中元素的顺序。在HashSet中,元素的添加、删除和查找操作具有较高的效率,这是因为HashSet通过HashMap来存储元素,利用哈希算法快速定位元素的位置...

    JAVA中HashMap的用法.docx

    在Java编程中,HashMap是基于哈希表实现的Map接口的一个实现,它是Java集合框架的重要组成部分,提供了高效、快速的键值对存储和检索能力。HashMap允许任何类型的对象作为键和值,但要求键必须是唯一的,且键和值都...

    15.【Map】_map_

    在多线程环境下,应使用`ConcurrentHashMap`,它提供线程安全的`Map`操作,效率比同步的`Hashtable`更高。 七、源码分析 深入理解`Map`的源码有助于优化代码性能和解决问题。例如,了解`HashMap`的桶(bucket)冲突...

Global site tag (gtag.js) - Google Analytics