[集合]线程安全的HashMap
一、一般模式下线程安全的HashMap
默认情况常用的HashMap都是线程不安全的,在多线程的环境下使用,常常会造成不可预知的,莫名其妙的错误。那么,我们如何实现一个线程安全的HashMap呢?其中一个可行的方式是使用Collectons.synchronizedMap() 方法来包装我们的HashMap。如下:
Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());
Collections.synchronizedMap()会生成一个SynchronizedMap,它使用委托模式,将自己HashMap相关的功能交给传入HashMap实现,二自己负责线程安全的相关实现,下面看看
SynchronizedMap的定义:
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L; private final Map<K,V> m; // Backing Map // 使用 mutex 实心对 map 的互斥操作
final Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
如在代码中看到的,所有对Map的操作都需要用 这个 mutex 来同步,以实现线程安全。比如说下面这些常见的对HashMap的操作方法:
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
除了以上看到的方法之外,其他的Map相关的方法有类似的操作。虽然这个包装的Map可以实现线程安全的要求,但是,它在多线程环境下的性能表现并不是很好,无论是对Map的读取还是写入,偶数需要获得 mutex 的同步锁,这会导致所有对Map的安全操作也会进入等待状态,知道mutex可用。 如果并发级别不高,那么这个 包装的Map可以基本满足要求,但是在搞并发的环境中,我们需要寻找新的解决方案。 ——---> 那就是我们的 ConcurrentHashMap.
二、提高"锁"性能的策略
1. 减少锁的持有时间
只在必要时进行同步,减少锁的持有时间。比如说在一个方法中只有一个变量需要同步,那么就没有必要对这整个方法都进行同步,而只需要同步这个变量即可。
// 无谓的加锁时间
public synchronied void syncMethod() { othrerMethod();
mutexMethod();
otherMethod();
} // 正确的加锁时间
public void syncMethod() { othrerMethod();
synchronied(this){
mutexMethod();
}
otherMethod();
}
2. 减小锁的粒度
在获取全局信息方法不频繁的时候,通过减小锁的粒度可以搞系统的吞吐量。
3. 读写分离锁替换独占锁
在读都写少的情况下,使用读写分离锁,多线程读时不阻塞,而只对写线程进行同步。
4. 锁分离
对不同功能的锁进行不同的锁策略。
5. 锁粗化
系统对于"锁"的调度也是需要性能消耗的,又是我们可以适当的加大锁的范围,比如说在循环中尽量减少对锁的请求和释放,而是在得到锁的情况,一次性把问题解决。
[集合]线程安全的HashMap的更多相关文章
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMa ...
- java集合框架之java HashMap代码解析
java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...
- Java集合框架之三:HashMap源码解析
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! HashMap在我们的工作中应用的非常广泛,在工作面试中也经常会被问到,对于这样一个重要的集合模型我们有必要弄清楚它的使用方法和它底层的实 ...
- java基础36 双例集合Map下的HashMap和TreeMap集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...
- java集合框架collection(4)HashMap和Hashtable的区别
HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别.主要的区别有:线程安全性,同步(synchronizatio ...
- Java集合系列(四):HashMap、Hashtable、LinkedHashMap、TreeMap的使用方法及区别
本篇博客主要讲解Map接口的4个实现类HashMap.Hashtable.LinkedHashMap.TreeMap的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 ...
- Java基础系列 - JAVA集合ArrayList,Vector,HashMap,HashTable等使用
package com.test4; import java.util.*; /** * JAVA集合ArrayList,Vector,HashMap,HashTable等使用 */ public c ...
- 非线程安全的HashMap 和 线程安全的ConcurrentHashMap
在平时开发中,我们经常采用HashMap来作为本地缓存的一种实现方式,将一些如系统变量等数据量比较少的参数保存在HashMap中,并将其作为单例类的一个属性.在系统运行中,使用到这些缓存数据,都可以直 ...
随机推荐
- Tornado中insert into sql语句的构造
#!/usr/bin/env python # -*- coding:utf-8 -*- d = {'name': 'alx', 'age': 18,'k1':123,'k2': 123} t = & ...
- Perl基础语法
一.脚本文件perl 代码可以写在一个文本文件中,以 .pl..PL 作为后缀.文件名可以包含数字,符号和字母,但不能包含空格,可以使用下划线(_)来替代空格.一个简单的Perl 文件名:rurun_ ...
- JDK的安装和环境配置
安装环境:网上下载的JDK一般都包含JRE在里面,安装JDK完成后会提示接着装JRE,如果没提示再去下载另装如:jdk_8u101_windows_x64_8.0.1010.13 配置环境:新建系统变 ...
- php 数据导出csv 注意问题。
总共10W数据每次下载到9.5W就停了. 加上这个就好了 ini_set('memory_limit','512M'): //脚本运行无时间限制. set_time_limit(0); 要设置一个se ...
- fail-fast 与 fail-save 机制的区别
link:https://blog.csdn.net/bigtree_3721/article/details/67095084
- IDEA02 利用Maven创建Web项目、为Web应用添加Spring框架支持、bean的创建于获取、利用注解配置Bean、自动装配Bean、MVC配置
1 环境版本说明 Jdk : 1.8 Maven : 3.5 IDEA : 专业版 2017.2 2 环境准备 2.1 Maven安装及其配置 2.2 Tomcat安装及其配置 3 详细步骤 3.1 ...
- 345. Reverse Vowels of a String翻转字符串中的元音字母
[抄题]: Write a function that takes a string as input and reverse only the vowels of a string. Example ...
- 基于Ubuntu16搭建Hadoop大数据完全分布式环境
[目的]:学习大数据 在此记录搭建大数据的过程. [系统环境] 宿主机操作系统:Win7 64位 虚拟机软件:Vmware workstation 12 虚拟机:Ubuntu 16 64位桌面版 [步 ...
- UCOSII在STM32F407上的移植
1.ucosii移植准备工作 1.1准备基础工程: 移植的时候需要一个基础工程,为了方便起见我们就选取跑马灯实验,作为ucossii移植的基础工程. 1.2Ucossii源码: 1)Micrium官网 ...
- Shell内置命令
主要Shell内置命令 Shell有很多内置在其源代码中的命令.这些命令是内置的,所以Shell不必到磁盘上搜索它们,执行速度因此加快.不同的Shell内置命令有所不同. A.2.1 bash内置命 ...