java HashMap问题
java 的HashMap是Map接口的一个实现,采用的是key-value键值存储,其中key是不能重复的,对于重复的key,将覆盖其value。同时HashMap的线程不安全的。
今天写了这样一个多线程代码,发现一个问题不理解,希望通过博客园的高手给予解答。
package com.mesnac.qc.A1; import java.util.HashMap; import java.util.Hashtable; public class Foo { private int x = 100; private HashMap hMap = new HashMap(); private Hashtable hTab = new Hashtable(); public int getX() { return x; } public HashMap getHMap() { return hMap; } public Hashtable getHTab() { return hTab; } public Hashtable htb(Object key,Object value) { hTab.put(key, value); return hTab; } public HashMap hfx(Object key,Object value) { hMap.put(key, value); return hMap; } public int fix(int y) { synchronized(this) { x = x - y; } return x; } }
package com.mesnac.qc.A1; import java.util.HashMap; import java.util.Hashtable; public class MyRunable implements Runnable{ private Foo a1 = new Foo(); public void run() { for(int i = 0;i < 3; i++) { a1.fix(20); a1.hfx(Integer.valueOf(i), Integer.valueOf(i)); a1.htb(Integer.valueOf(i), Integer.valueOf(i)); try { Thread.sleep(1); } catch (Exception e) { // TODO: handle exception } System.out.println(Thread.currentThread().getName()+"当前Foo值"+a1.getX()); System.out.println(Thread.currentThread().getName()+"当前HMAP值"+a1.getHMap()); System.out.println(Thread.currentThread().getName()+"当前HTable值"+a1.getHTab()); } } public static void main(String args[]) { MyRunable aMyRunable = new MyRunable(); Thread a = new Thread(aMyRunable,"Thread-A"); Thread bThread = new Thread(aMyRunable,"Thread-B"); a.start(); bThread.start(); HashMap t1 = new HashMap(); t1.put(Integer.valueOf(0), Integer.valueOf(0)); t1.put(Integer.valueOf(0), Integer.valueOf(0)); t1.put(Integer.valueOf(0), Integer.valueOf(0)); t1.put(Integer.valueOf(0), Integer.valueOf(0)); Hashtable t2 = new Hashtable(); t2.put(Integer.valueOf(0), Integer.valueOf(0)); t2.put(Integer.valueOf(0), Integer.valueOf(0)); t2.put(Integer.valueOf(0), Integer.valueOf(0)); t2.put(Integer.valueOf(0), Integer.valueOf(0)); t2.put(Integer.valueOf(0), Integer.valueOf(1)); System.out.println(t1); System.out.println(t2); } }
主要是两个线程去操作HashMap。我知道线程不安全,但是多次运行这个程序。会发现HashMap中存在 {2=2,1=1,0=0,0=0}的情况,查阅JDK,发现HashMap的存储是根据key获得一个hash值,然后执行key1==null?key2==null:key1.equal(key2)的算法,不理解为什么会产生重复的值。难道是因为第一个0,0存入的时候,执行到hash算法之后,但是没保存,第二个线程也执行到判断,这样两个都保存进去了么?
希望博客园大牛给予解答。。。