一、HashMap在非线程安全的环境下使用会出现什么样的问题?

public class HashMapMultiThread {
static Map<String,String> map = new HashMap<String,String>();
public static class AddThread implements Runnable{
int start = 0 ;
public AddThread(int start){
this.start = start;
}
@Override
public void run() {
for (int i = 0; i < 100000; i+=2) {
map.put(Integer.toString(i), Integer.toBinaryString(i)); }
}
} public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new HashMapMultiThread.AddThread(0));
Thread t2 = new Thread(new HashMapMultiThread.AddThread(1));
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(map.size());
}
}

上述代码使用t1和t2两个线程同时对HashMap进行put()操作,如果一切正常,我们期望得到的map.size()就是100000.但实际上,你可能会得到以下三种情况(注意,这里使用JDK7进行试验):

第一:程序正常结束,并且结果也是符合预期的。HashMap的大小为100000.

第二:程序正常结束,但结果不符合预期,而是一个小于100000的数字,比如98868.

第三:程序永远无法结束。并发形成循环链表,导致死循环。

二、ConcurrentHashMap不能解决所有线程安全问题

对于ConcurrentHashMap,如果只调用get或put方法是线程安全的,但你调用get后再调用put之前,如果有另一个线程也调用了put就很可能把前面的操作结果覆盖了,因为违反了原则操作的规则。此时可用putIfAbsent方法代替。如下面的例子

public class ConcurrentHashMapTest {

    private static final ConcurrentMap<String, AtomicInteger> CACHE_MAP = new ConcurrentHashMap<>();
private static final String KEY = "test"; private static class TestThread implements Runnable{
@Override
public void run() {
if(CACHE_MAP.get(KEY)==null){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
CACHE_MAP.put(KEY, new AtomicInteger());
}
CACHE_MAP.get(KEY).incrementAndGet();
}
} public static void main(String[] args) {
new Thread(new TestThread()).start();
new Thread(new TestThread()).start();
new Thread(new TestThread()).start();
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("次数:"+CACHE_MAP.get(KEY).get());
}
}

Map容器线程安全问题的更多相关文章

  1. map的线程安全问题

    为什么HashMap是线程不安全的 总说 HashMap 是线程不安全的,不安全的,不安全的,那么到底为什么它是线程不安全的呢?要回答这个问题就要先来简单了解一下 HashMap 源码中的使用的存储结 ...

  2. Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间以及单例多例的区别、SSH线程安全问题

    首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的.在这里需要提醒一下,如果我们在class中没有显示的声 ...

  3. 关于 SimpleDateFormat 的非线程安全问题及其解决方案

    一直以来都是直接用SimpleDateFormat开发的,没想着考虑线程安全的问题,特记录下来(摘抄的): 1.问题: 先来看一段可能引起错误的代码: package test.date; impor ...

  4. 被我们忽略的HttpSession线程安全问题

    1. 背景 最近在读<Java concurrency in practice>(Java并发实战),其中1.4节提到了Java web的线程安全问题时有如下一段话: Servlets a ...

  5. 【GoLang】GoLang map 非线程安全 & 并发度写优化

    Catena (时序存储引擎)中有一个函数的实现备受争议,它从 map 中根据指定的 name 获取一个 metricSource.每一次插入操作都会至少调用一次这个函数,现实场景中该函数调用更是频繁 ...

  6. javaweb回顾第六篇谈一谈Servlet线程安全问题

    前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例 ...

  7. stl空间配置器线程安全问题补充

    摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关 ...

  8. 《day15---多线程安全问题_JDK1.5的锁机制》

    //15同步问题的分析案例以及解决思路 //两个客户到一个银行去存钱,每个客户一次存100,存3次. //问题,该程序是否有安全问题,如果有,写出分析过程,并定于解决方案. /* 发现运行结果: su ...

  9. 浅析Struts1和Struts2的Action线程安全问题 转

    浅析Struts1和Struts2的Action线程安全问题  转 http://blog.csdn.net/virgoboy2004/article/details/5876133 [问题描述]最近 ...

随机推荐

  1. C#使用CurrentUICulture切换语言

    1. 创建2个窗口   2. 窗口1属性Localizable设置为True,Language选择英语(美国) 然后把窗口1中控件的Text由中文编辑成英文,Form2一样设置.   此时,Form1 ...

  2. C#报错"线程间操作无效: 从不是创建控件“XXX”的线程访问它"--解决示例

    C# Winform程序中,使用线程对界面进行更新需要特殊处理,否则会出现异常“线程间操作无效: 从不是创建控件“taskView”的线程访问它.” 在网文“http://www.cnblogs.co ...

  3. django_session

    基于cookie做用户验证时:敏感信息不适合放在cookie中 session依赖cookie session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 s ...

  4. PS 如何制作WIN7的玻璃化透明窗口效果

    1 绘制一个圆角矩形,并将不透明度设为16%以及添加投影效果   2 再次添加外发光效果   3 新建一个图层,再填充一下这个圆角矩形(可以填充为任意颜色,只要和别的颜色区分开来)   4 选中这个区 ...

  5. Unity开发规范(个人习惯,仅供參考)

    近期整理了一下unity里的文件夹使用和脚本上的一些规范,这个看个人习惯,仅供參考 1.unity中的Project文件夹      总体文件夹大致例如以下:            按资源种类分目录. ...

  6. 微信小程序制作商 业务流程

  7. Linux退出时出现there are stopped jobs如何解决?

    Linux 使用exit时出现there are stopped jobs如何解决? 这是因为一些命令被挂起了, 在后台驻留,需要关闭. 解决问题: 输入命令jobs -l显示停止进程的详细列表 可以 ...

  8. C++静态库与动态库深入研究

    什么是库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可以被操 ...

  9. 获取css信息

    一般情况是用style直接获取css信息但是style只能获取到卸载行内的样式外链的和嵌入的样式会获取不到 2.5 用下面方法获取外链和嵌入的css样式 这种方法只能用于读取 window.getCo ...

  10. 3.nginx反向代理服务器+负载均衡

    nginx反向代理服务器+负载均衡 用nginx做反向代理和负载均衡非常简单, 支持两个用法: 1个proxy, 1个upstream,分别用来做反向代理,和负载均衡 以反向代理为例, nginx不自 ...