博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Map容器线程安全问题
阅读量:6082 次
发布时间:2019-06-20

本文共 2253 字,大约阅读时间需要 7 分钟。

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

public class HashMapMultiThread {      static Map
map = new HashMap
(); 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
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()); }}

 

转载地址:http://iykwa.baihongyu.com/

你可能感兴趣的文章
开发环境、生产环境、测试环境的基本理解和区别
查看>>
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>