- 浏览: 101858 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (99)
- 经济 (1)
- dwr (2)
- 测试 (0)
- java (29)
- resin (1)
- oracle (3)
- 感悟 (1)
- jvm (15)
- mina2 (5)
- j2se (12)
- linux (28)
- protobuf (1)
- tcp/ip (0)
- jdbc (0)
- 数据库 (4)
- 游戏 (0)
- 技术文档 (1)
- nosql (2)
- 算法 (2)
- apache (2)
- mysql (1)
- hashcode (1)
- spring (2)
- quartz (5)
- netcat (2)
- 分页 (1)
- 正则 (0)
- shell (1)
- lsof (1)
- nginx (1)
- git (1)
最新评论
-
fys124974704:
你试下将第三条写成以下这样,你会发现你的结论不对:select ...
ORACLE分页SQL语句 -
ikon:
两个乘数没有转成integer,而是当成字符串;BigInte ...
计算任意2个正整数的乘积 -
kidding87:
效率不是很高,思路没有问题,但是你的两个乘数输入都都转为Int ...
计算任意2个正整数的乘积 -
k1280000:
------------------------同意!
学习之道
大家都知道HashMap不是线程安全的,但是大家的理解可能都不是十分准确。很显然读写同一个key会导致不一致大家都能理解,但是如果读写一个不变的对象会有问题么?看看下面的代码就明白了。
1 import java.util.HashMap;
2 import java.util.Map;
3 import java.util.Random;
4 import java.util.concurrent.ExecutorService;
5 import java.util.concurrent.Executors;
6 import java.util.concurrent.TimeUnit;
7 import java.util.concurrent.atomic.AtomicInteger;
8
9 public class HashMapTest2 {
10 static void doit() throws Exception{
11 final int count = 200;
12 final AtomicInteger checkNum = new AtomicInteger(0);
13 ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(100);
14 //
15 final Map<Long, String> map = new HashMap<Long, String>();
16 map.put(0L, "www.imxylz.cn");
17 //map.put(1L, "www.imxylz.cn");
18 for (int j = 0; j < count; j++) {
19 newFixedThreadPool.submit(new Runnable() {
20 public void run() {
21 map.put(System.nanoTime()+new Random().nextLong(), "www.imxylz.cn");
22 String obj = map.get(0L);
23 if (obj == null) {
24 checkNum.incrementAndGet();
25 }
26 }
27 });
28 }
29 newFixedThreadPool.awaitTermination(1, TimeUnit.SECONDS);
30 newFixedThreadPool.shutdown();
31
32 System.out.println(checkNum.get());
33 }
34
35 public static void main(String[] args) throws Exception{
36 for(int i=0;i<10;i++) {
37 doit();
38 Thread.sleep(500L);
39 }
40 }
41 }
42
结果一定会输出0么?结果却不一定。比如某一次的结果是:
0
3
0
0
0
0
9
0
9
0
查看了源码,其实出现这个问题是因为HashMap在扩容是导致了重新进行hash计算。
在HashMap中,有下面的源码:
1 public V get(Object key) {
2 if (key == null)
3 return getForNullKey();
4 int hash = hash(key.hashCode());
5 for (Entry<K,V> e = table[indexFor(hash, table.length)];
6 e != null;
7 e = e.next) {
8 Object k;
9 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
10 return e.value;
11 }
12 return null;
13 }
2 if (key == null)
3 return getForNullKey();
4 int hash = hash(key.hashCode());
5 for (Entry<K,V> e = table[indexFor(hash, table.length)];
6 e != null;
7 e = e.next) {
8 Object k;
9 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
10 return e.value;
11 }
12 return null;
13 }
在indexOf中就会导致计算有偏移。
1 static int indexFor(int h, int length) {
2 return h & (length-1);
3 }
很显然在Map的容量(table.length,数组的大小)有变化时就会导致此处计算偏移变化。这样每次读的时候就不一定能获取到目标索引了。为了证明此猜想,我们改造下,变成以下的代码。
final Map<String, String> map = new HashMap<String, String>(10000);
执行多次结果总是输出:
0
0
0
0
0
0
0
0
0
0
当然了如果只是读,没有写肯定没有并发的问题了。改换Hashtable或者ConcurrentHashMap肯定也是没有问题了。
发表评论
-
Quartz定时任务学习(一)简单任务
2012-04-27 12:30 837学习quartz首先了解三个概念: 调度器:负责调度作 ... -
介绍Quartz
2012-04-27 12:22 1403介绍Quartz Quartz是一个开源的任务调度 ... -
理解Quartz触发器(1)
2012-04-27 11:37 856Quartz中一个Job往往是 ... -
Quartz中SimpleTrigger的探讨
2012-04-27 11:34 7001.来写一个每隔10秒启动一次任务的例子. import j ... -
关于hashcode 里面 使用31 系数的问题
2012-03-27 09:16 799首先我们来了解一下h ... -
理解Java对象序列化
2012-02-15 09:38 688关于Java序列化的文章早 ... -
认识Arrays(一)打印
2012-02-03 16:52 566Arrays提供了一组操作array的静态方法。 一、基本类 ... -
apache.commons.io 笔记1
2012-01-19 17:13 1060看看,常见的东西都有了,如查询盘的剩余空间,文件夹大小, ... -
commons-io 自动加载配置文件
2012-01-19 16:55 737org.apache.commons.io.monitor.F ... -
oracle java数据类型对应表
2011-12-05 13:37 0[img]http://dl.iteye.com/upload ... -
Iterator和Enumeration的主要区别
2011-11-25 14:38 843(1)java中的集合类都提供了返回Iterator的方法 ... -
计算任意2个正整数的乘积
2011-11-12 21:36 1196接上一篇整数的阶乘算法,来计算2个正整数的乘积; 算法如下: ... -
计算任意正整数的阶乘
2011-11-12 20:17 664由于阶乘的结果会超出java数据类型的最大范围,所 ... -
Java调用外部程序技巧
2011-11-08 09:17 791前些天使用Java调用外部程序的时候,发现线程会堵塞在wa ... -
多核平台下的JAVA优化
2011-11-08 09:12 627现在多核CPU是主流。利用多核技术,可以有效发挥硬件的能力 ... -
使用 Eclipse Memory Analyzer 进行堆转储文件分析
2011-11-07 17:09 765http://www.ibm.com/developerwor ... -
infoQ 文档ppt
2011-11-07 11:43 1245http://www.docin.com/app/user/c ... -
游戏性能监控
2011-11-07 10:18 01、cpu消耗(耗时)监控 在功能代码前后取时间值,相减,发 ... -
使用Cacti监控你的网络(一)- Cacti概述及工作流程
2011-11-07 09:36 670http://blog.sina.com.cn/s/b ... -
浅析 Java Thread.join()
2011-10-29 09:25 852一、在研究join的用法之前,先明确两件事情。 1.join ...
相关推荐
HashMap为什么是线程不安全的?如何解决HashMap的线程不安全问题?
经常会看到说HashMap是线程不安全的,ConcurrentHashMap是线程安全的等等说法,不禁有个疑问,什么是线程安全?什么样的类是线程安全的? 1.什么是线程安全性(what) 线程安全定义,最核心是正确性, 正确性:多个...
高级程序员必会的HashMap的线程安全问题,适用于0~2年的
HashMap和HashTable的区别?但是如果想线程安全有想效率高?
NULL 博文链接:https://flyfoxs.iteye.com/blog/1198030
哈希映射线程测试使用 Maven 构建和运行 mvn exec:java
以结构图记录自己的记录自己面对的感触
这就有可能导致A线程和B线程同时对一个数组扩容,A线程扩容后替换掉老数组,这时B线程使用的数组实际上是A线程扩容后的数组,就会产生线程安全问题。 死锁原因 比如,当前集合数组长度为2,已经有两个元素被放在了...
线程安全与不安全集合 线程不安全集合: ArrayList LinkedList HashMap HashSet TreeMap TreeSet StringBulider 线程安全集合: Vector HashTable Properties 集合线程安全与解决方案 ArrayList...
Golang无锁线程安全的HashMap,为最快的读取访问进行了优化
HashMap是线程安全的吗?线程安全的Map都有哪些?HashMap的数据结构是怎样的?HashMap的链表结构设计是用来解决什么问题的?HashMap中的g
如果我么需要有一个线程安全的HashMap,可以使用Collections.synchronizedMap(Map m)方法获得线程安全的HashMap,也可以使用ConcurrentHashMap类创建线程安全的map。 存储的元素在jdk1.7当中是Entry作为存储的
Java标准库中的一些类如ArrayList、HashMap和SimpleDateFormat,都是非线程安全的,在多线程环境下直接使用它们可能导致一些非预期的结果,甚至是一些灾难性的结果。一般来说,Java标准库中的类在其API文档中会说明...
hashmap如何解决hash冲突,为什么hashmap中的链表需要转成红黑树? hashmap什么时候会触发扩容? jdk1.8之前并发操作hashmap时为什么会有死循环的问题?...CopyOnWriteArrayList是如何保证线程安全的?
什么是HashMap? HashMap是一个存储key-value...2.HashMap是线程不安全的,其速度比较快 3.HashMap在存储key的值时,允许为NULL 4.对于输入数据的顺序与输出数据的顺序没有特别要求(如果有特别要求,要用LinkedHashMap)
因此,在使用HashMap时需要进行同步处理或者使用线程安全的HashMap实现类。 动态扩容:当HashMap中的元素数量超过了容量(默认为16)与负载因子(默认为0.75)的乘积时,HashMap会自动扩容,即创建一个新的数组,并将...
HashMap 不是线程安全的;多线程环境下,建议使用 ConcurrentHashMap,或者使用 Collections.synchronizedMap(hashMap) 将 HashMap 转成线程同步的。 只能使用关联的键来获取值。 HashMap 只能存储对象,所以基本...
HashMap的存储结构 HashMap内部采用数组和链表的方式存储数据,每个元素都包含...HashMap通过synchronized关键字实现线程安全,确保多线程环境下的数据一致性和并发访问的安全性,避免潜在的竞争条件和数据不一致问题。
线程安全的集合 线程安全的 List CopyOnWriteArrayList 线程安全的Set 线程安全的Map ConcurrentHashMap ConcurrentSkipListMap java集合 线程不安全的集合 HashMap的特点 HashMap在Jdk8之前使用拉链法实现,jdk8...
1) // increase counter...count := atomic.LoadInt64(counter) // read counter基准测试以线程安全的方式从哈希映射中进行读取的速度几乎与以不安全的方式从标准Golang映射中进行读取的速度相同,是Go的sync.Map的...