ConcurrentHashMap并不是绝对线程安全的
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapDemo1 { private static Map<Long, Integer> widgetCacheMap = new ConcurrentHashMap<Long, Integer>(); /**
* @param args
*/
public static void main(String[] args) {
for (int i = ; i < ; i++) {
Thread tt = new Thread(new Rund());
tt.start();
}
} static class Rund implements Runnable { public void run() {
test();
} /**
* 1W次,总有那么几次线程不安全
*/
public void test() {
synchronized ("") {// 解决方案
ConcurrentHashMapDemo1 tt = new ConcurrentHashMapDemo1();
tt.set();
int s1 = widgetCacheMap.get(1L).intValue();
tt.change();
int s2 = widgetCacheMap.get(1L).intValue();
if (s1 == s2) {
System.out.println(s1 + ":" + s2);
}
}
} } public void set() {
Map<Long, Integer> mm = new HashMap<Long, Integer>();
mm.put(1L, );
widgetCacheMap = mm;
} public void change() {
Map<Long, Integer> mm = new HashMap<Long, Integer>();
mm.put(1L, );
widgetCacheMap = mm;
} }
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; public class ConcurrentHashMapDemo2 { public static void main(String[] args) throws InterruptedException {
for (int i = ; i < ; i++) {
System.out.println(test());
}
} private static int test() throws InterruptedException {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = ; i < ; i++) {
pool.execute(new MyTask(map));
}
pool.shutdown();
pool.awaitTermination(, TimeUnit.DAYS); return map.get(MyTask.KEY);
}
} class MyTask implements Runnable { public static Object lock = new Object(); public static final String KEY = "key"; private ConcurrentHashMap<String, Integer> map; public MyTask(ConcurrentHashMap<String, Integer> map) {
this.map = map;
} @Override
public void run() {
for (int i = ; i < ; i++) {
synchronized (lock) { // 解决方案
this.addup();
}
}
} private void addup() {
if (!map.containsKey(KEY)) {
map.put(KEY, );
} else {
map.put(KEY, map.get(KEY) + );
}
}
}
总结:ConcurrentHashMap是线程安全的,那是在他们的内部操作,其外部操作还是需要自己来保证其同步的,特别是静态的ConcurrentHashMap,其有更新和查询的过程,要保证其线程安全,需要syn一个不可变的参数才能保证其原子性
ConcurrentHashMap并不是绝对线程安全的的更多相关文章
- ConcurrentHashMap、synchronized与线程安全
明明用了ConcurrentHashMap,可是始终线程不安全, 下面我们来看代码: public class Test40 { public static void main(String[] ar ...
- ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点
ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含 ...
- HashMap、HashTable、ConcurrentHashMap、HashSet区别 线程安全类
HashMap专题:HashMap的实现原理--链表散列 HashTable专题:Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析 Hash,Tree数据结构时 ...
- 【图解】面试题:ConcurrentHashMap是如何保证线程安全的
注意:JDK1.7与JDK1.8中的ConcurrentHashMap主要延续HashMap的设计与思想,是在其基础上进行的相应优化 1.JDK1.7中的底层实现原理 (1)JDK1.7Concurr ...
- ConcurrentHashMap并不是完全的线程安全
ConcurrentHashMap通过分段锁的方式实现了高效率的线程安全,但是它能否在所有高并发场景中都能保证线程安全呢? public class TestClass { private Concu ...
- ConcurrentHashMap的size方法是线程安全的吗?
前言 之前在面试的过程中有被问到,ConcurrentHashMap的size方法是线程安全的吗? 这个问题,确实没有答好.这次来根据源码来了解一下,具体是怎么一个实现过程. ConcurrentHa ...
- 为什么ConcurrentHashMap是线程安全的?
ConcurrentHashMap 是 HashMap 的多线程版本,HashMap 在并发操作时会有各种问题,比如死循环问题.数据覆盖等问题.而这些问题,只要使用 ConcurrentHashMap ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
- Java线程面试题 Top 50 (转载)
转载自:http://www.cnblogs.com/dolphin0520/p/3958019.html 原文链接:http://www.importnew.com/12773.html 本文由 ...
随机推荐
- 在EntityFramework6中管理DbContext的正确方式——4DbContextScope:一个简单的,正确的并且灵活的管理DbContext实例的方式(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
- [iOS] UIView的clipsTobounds属性
如题,有两个view: view1,view2view2添加view1到中,如果view2大于view1,或者view2的坐标不全在view1的范围内,view2是盖着view1的,意思就是超出的部份 ...
- [翻译] FMDB
FMDB https://github.com/ccgus/fmdb This is an Objective-C wrapper around SQLite: http://sqlite.org/ ...
- 魅族MX3 smart bar处失灵
MX3的分辨率是1800X1080,改成1750X1080 adb shell wm size 1080x1750
- C结构体
什么是结构体? 简单的来说,结构体就是个能够包含不同数据类型的一个结构,他是一种能够自己定义的数据类型,他的特点和数组主要有两点不同,首先结构体能够在一个结构中声明不同的数据类型,第二相同结构的结构体 ...
- MongoDB:如何正常关闭服务(转)
原文链接:MongoDB:关闭服务 MongoDB 提供几种关闭服务的命令,具体为以下: 一 使用 Crtl+C 关闭 [mongo@redhatB data]$ mongod --dbpath=/ ...
- Reorder List leetcode java
题目: Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must d ...
- js常用的事件对象
事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event. ...
- 如何解决 SQL Server 中的锁升级所致的阻塞问题
概要 锁升级为表锁插入转换很多细粒度的锁 (如行或页锁) 的过程.Microsoft SQL Server 动态确定何时执行锁升级.作出决定之前,SQL Server 将特定的扫描,整个事务,并且用于 ...
- idea 设置代码的颜色