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算法之后,但是没保存,第二个线程也执行到判断,这样两个都保存进去了么?

 

希望博客园大牛给予解答。。。

posted @ 2012-07-04 09:56  庸蛹  阅读(301)  评论(0编辑  收藏  举报