2014-11-13 2 views
1

ConcurrentHashMap은 HashTable보다 훨씬 빠릅니다. 다음 코드가 왜 나타나지 않는지 궁금합니다.ConcurrentHaspMap 대 HashTable 실행 시간

다음 코드에서 일부 숫자는 ConcurrentHashMap (chm)과 HashTable (ht)에 모두 채워집니다. chm 또는 ht 요소에서 동일한 작업을 수행하고 실행 시간을 ms 단위로 반환하는 두 개의 동등한 Callable (하나는 chm 용, 다른 하나는 ht 용)이 있습니다.

hm의 실행 시간이 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

사과를 오렌지와 비교하고 있습니다.

ConcurrentHashMap은 동시입니다. 즉, 더 많은 스레드에서 동시에 사용할 수 있습니다.

Hashtable이 동기화되어 있습니다 (일부 작업 방법은 동기화 됨 - get/put/clear ...) -> 함께 작동하는 것은 상호 배타적입니다. iterator는 스레드로부터 안전하지 않으므로 다른 스레드에서 iterating 할 때 동시에 수정하려고하면 ConcurrentModificationException이 throw 될 수 있습니다 (메모리 가시성이 아닐 수도 있음).

단일 스레드에서 맵을 통한 반복 성능을 비교합니다 (각 맵은 하나의 스레드에서 실행 됨). 그렇다면 Hashtable은 이 더 빠른입니다. 구현이 많이 일 때이 더 간단합니다 (스레드가 안전하지 않으며 동시 수정 등을 지원하지 않기 때문입니다).

지도에 대한 동시 수정/액세스와 함께 다른 벤치 마크를 작성하면 ConcurrentHashMap이 더 빠르다는 것을 알 수 있습니다. (동시이기 때문에 :-) Hashtable은 그렇지 않습니다.