ConcurrentHashMap与HashTable执行时间

时间:2014-11-13 13:12:57

标签: hashtable concurrenthashmap

在文献中你可以发现,ConcurrentHashMap比HashTable快得多。 我只是想知道为什么下面的代码没有显示出来。

在下面的代码中,ConcurrentHashMap(chm)和HashTable(ht)中都填充了一些数字。 有两个等效的Callable(一个用于chm,另一个用于ht),它们对chm或ht元素执行相同的操作,并以ms为单位返回执行时间。

我的执行时间少于chm的一半。

public class ConcurrentHashMapDemo {

    static ConcurrentHashMap<Long, Double> chm;
    static Hashtable<Long, Double> ht;
    int result1;
    int result2;
    static long numbers = 1000000;

    public ConcurrentHashMapDemo(){
        chm = new ConcurrentHashMap<>();
        ht = new Hashtable<>();
        result1=0;
        result2=0;
    }
    // just do some operation with map or table elements
    private class Th1 implements Callable<Integer>{
        public Integer call(){
            long base = System.currentTimeMillis();
            for(Entry<Long, Double> e: chm.entrySet()){
                result1+=e.getKey();
                result1+=(int)(e.getValue()*10);
            }
            long time = System.currentTimeMillis();
            return (int)(time-base);
        }
    }

    private class Th2 implements Callable<Integer>{
        public Integer call(){
            long base = System.currentTimeMillis();
            for(Entry<Long, Double> e: ht.entrySet()){
                result2+=e.getKey();
                result2+=(int)(e.getValue()*10);
            }
            long time = System.currentTimeMillis();
            return (int)(time-base);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ConcurrentHashMapDemo chmd = new ConcurrentHashMapDemo();
        for(long i=0;i<numbers;i++){
            chm.put((Long)i, Math.sqrt(i));
            ht.put((Long)i, Math.sqrt(i));
        }
        ExecutorService ex = Executors.newCachedThreadPool();
        try {
            Future<Integer>s11 = ex.submit(chmd.new Th1());
            System.out.println("chm "+s11.get());   // appr. 220
            Thread.sleep(1000);
            Future<Integer>s21 = ex.submit(chmd.new Th2());
            System.out.println("ht "+s21.get());    // appr. 110
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        ex.shutdown();
    }
}

1 个答案:

答案 0 :(得分:1)

你在这里将苹果与橙子进行比较。

ConcurrentHashMap 是并发的 - 这意味着您可以在更多线程中同时使用它。

Hashtable 是同步的(使用它的一些方法是同步的 - get / put / clear ...) - &gt;与它的操作是相互排斥的。请注意迭代器不是线程安全的,因此如果在其他线程中迭代它时尝试同时修改它,它可能(可能不会 - 内存可见性)抛出ConcurrentModificationException。

您可以比较单个线程中迭代的迭代性能(每个映射将在一个线程中运行)。然后Hashtable 更快因为它的实现非常更简单(它不是线程安全的,它不支持并发修改等。)

如果您要通过并发修改/访问地图来创建不同的基准,您会发现ConcurrentHashMap更快(因为它是并发的:-)而Hashtable不是)。