Map容器线程安全问题
一、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容器线程安全问题的更多相关文章
- map的线程安全问题
为什么HashMap是线程不安全的 总说 HashMap 是线程不安全的,不安全的,不安全的,那么到底为什么它是线程不安全的呢?要回答这个问题就要先来简单了解一下 HashMap 源码中的使用的存储结 ...
- Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间以及单例多例的区别、SSH线程安全问题
首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的.在这里需要提醒一下,如果我们在class中没有显示的声 ...
- 关于 SimpleDateFormat 的非线程安全问题及其解决方案
一直以来都是直接用SimpleDateFormat开发的,没想着考虑线程安全的问题,特记录下来(摘抄的): 1.问题: 先来看一段可能引起错误的代码: package test.date; impor ...
- 被我们忽略的HttpSession线程安全问题
1. 背景 最近在读<Java concurrency in practice>(Java并发实战),其中1.4节提到了Java web的线程安全问题时有如下一段话: Servlets a ...
- 【GoLang】GoLang map 非线程安全 & 并发度写优化
Catena (时序存储引擎)中有一个函数的实现备受争议,它从 map 中根据指定的 name 获取一个 metricSource.每一次插入操作都会至少调用一次这个函数,现实场景中该函数调用更是频繁 ...
- javaweb回顾第六篇谈一谈Servlet线程安全问题
前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例 ...
- stl空间配置器线程安全问题补充
摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关 ...
- 《day15---多线程安全问题_JDK1.5的锁机制》
//15同步问题的分析案例以及解决思路 //两个客户到一个银行去存钱,每个客户一次存100,存3次. //问题,该程序是否有安全问题,如果有,写出分析过程,并定于解决方案. /* 发现运行结果: su ...
- 浅析Struts1和Struts2的Action线程安全问题 转
浅析Struts1和Struts2的Action线程安全问题 转 http://blog.csdn.net/virgoboy2004/article/details/5876133 [问题描述]最近 ...
随机推荐
- C#使用CurrentUICulture切换语言
1. 创建2个窗口 2. 窗口1属性Localizable设置为True,Language选择英语(美国) 然后把窗口1中控件的Text由中文编辑成英文,Form2一样设置. 此时,Form1 ...
- C#报错"线程间操作无效: 从不是创建控件“XXX”的线程访问它"--解决示例
C# Winform程序中,使用线程对界面进行更新需要特殊处理,否则会出现异常“线程间操作无效: 从不是创建控件“taskView”的线程访问它.” 在网文“http://www.cnblogs.co ...
- django_session
基于cookie做用户验证时:敏感信息不适合放在cookie中 session依赖cookie session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 s ...
- PS 如何制作WIN7的玻璃化透明窗口效果
1 绘制一个圆角矩形,并将不透明度设为16%以及添加投影效果 2 再次添加外发光效果 3 新建一个图层,再填充一下这个圆角矩形(可以填充为任意颜色,只要和别的颜色区分开来) 4 选中这个区 ...
- Unity开发规范(个人习惯,仅供參考)
近期整理了一下unity里的文件夹使用和脚本上的一些规范,这个看个人习惯,仅供參考 1.unity中的Project文件夹 总体文件夹大致例如以下: 按资源种类分目录. ...
- 微信小程序制作商 业务流程
- Linux退出时出现there are stopped jobs如何解决?
Linux 使用exit时出现there are stopped jobs如何解决? 这是因为一些命令被挂起了, 在后台驻留,需要关闭. 解决问题: 输入命令jobs -l显示停止进程的详细列表 可以 ...
- C++静态库与动态库深入研究
什么是库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可以被操 ...
- 获取css信息
一般情况是用style直接获取css信息但是style只能获取到卸载行内的样式外链的和嵌入的样式会获取不到 2.5 用下面方法获取外链和嵌入的css样式 这种方法只能用于读取 window.getCo ...
- 3.nginx反向代理服务器+负载均衡
nginx反向代理服务器+负载均衡 用nginx做反向代理和负载均衡非常简单, 支持两个用法: 1个proxy, 1个upstream,分别用来做反向代理,和负载均衡 以反向代理为例, nginx不自 ...