测试HashTable、Collections.synchronizedMap和ConcurrentHashMap的性能

    对于map的并发操作有HashTable、Collections.synchronizedMap和ConcurrentHashMap三种,到底性能如何呢?

测试代码:

package com.yangyang;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class T {
    /**用于测试的线程数量**/
    public static final int threads = 100;
    /**每个线程往map中塞的数量**/
    public static final int NUMBER =100;

    public static void main(String[] args) throws Exception{
        Map<String, Integer> syncHashMap=Collections.synchronizedMap(new HashMap<String, Integer>());
        Map<String, Integer> concurrentHashMap=new ConcurrentHashMap<String, Integer>();
        Hashtable<String, Integer> hashtable=new Hashtable<String, Integer>();

        long totalA = 0;
        long totalB = 0;
        long totalC = 0;
        //循环10此,累计时间,便于观察
        for (int i = 0; i <= 10; i++) {
        // System.out.println("第"+i+"次测试put方法");
          totalA += testPut(syncHashMap);
          totalB += testPut(concurrentHashMap);
          totalC += testPut(hashtable);
        }
        System.out.println("Put time HashMapSync=" + totalA + "ms.");
        System.out.println("Put time ConcurrentHashMap=" + totalB + "ms.");
        System.out.println("Put time Hashtable=" + totalC + "ms.");

        totalA = 0;
        totalB = 0;
        totalC = 0;
        for (int i = 0; i <= 10; i++) {
          totalA += testGet(syncHashMap);
          totalB += testGet(concurrentHashMap);
          totalC += testGet(hashtable);
        }
        System.out.println("Get time HashMapSync=" + totalA + "ms.");
        System.out.println("Get time ConcurrentHashMap=" + totalB + "ms.");
        System.out.println("Get time Hashtable=" + totalC + "ms.");

    }

    private static long testPut(Map<String, Integer> map) throws Exception{
        long start = System.currentTimeMillis();

        //同时开threads个线程
        for (int i = 0; i < threads; i++) {
            new MapPutThread(map).start();
        }
        while (MapPutThread.counter > 0) {
          Thread.sleep(1);
        }
        return System.currentTimeMillis() - start;
    }

     public static long testGet(Map<String, Integer> map) throws Exception {
        long start = System.currentTimeMillis();
        for (int i = 0; i < threads; i++) {
          new MapGetThread(map).start();
        }
        while (MapGetThread.counter > 0) {
          Thread.sleep(1);
        }
        return System.currentTimeMillis() - start;
     }
}
/**
 * put线程类
 * @author shunyang
 * @date 2015年3月6日 下午4:24:42
 */
class MapPutThread extends Thread{

      static int counter = 0;//计数器
      static Object lock = new Object();//用于同步的对象锁
      private Map<String, Integer> map;
      private String key = this.getId() + "";

      MapPutThread(Map<String, Integer> map) {
        synchronized (lock) {
          counter++;//每调用一次构建函数,计数器加1
     //     System.out.println("线程key为:"+key+"的构造函数运行,当前counter为:"+counter);
        }
        this.map = map;
      }

      @Override
      public void run() {
        for (int i = 1; i <= T.NUMBER; i++) {
          map.put(key, i);
        //  System.out.println("线程key为:"+key+"的第"+i+"个run方法运行,设置的i为::"+i);
        }
        synchronized (lock) {
          counter--;//每当往map中put一个值后,计算器减1
       //   System.out.println("线程key为:"+key+"的run()运行,当前counter为:"+counter);
        }
      }
}
/**
 * get线程类
 * @author shunyang
 * @date 2015年3月6日 下午4:24:52
 */
class MapGetThread extends Thread {

  static int counter = 0;
  static final Object lock = new Object();
  private Map<String, Integer> map;
  private String key = this.getId() + "";

  MapGetThread(Map<String, Integer> map) {
    synchronized (lock) {
      counter++;
    }
    this.map = map;
  }

  @Override
  public void run() {
    for (int i = 1; i <= T.NUMBER; i++) {
      map.get(key);
    }
    synchronized (lock) {
      counter--;
    }
  }
}

当每次启动100个线程,每个线程往map中塞100个数据的时候,结果:

当每次启动1000个线程,每个线程往map中塞1000个数据的时候,结果:

当每次启动10000个线程,每个线程往map中塞10000个数据的时候,结果:

结论:当线程越多时,

ConcurrentHashMap的性能比同步的HashMap快一倍左右

同步的HashMap和Hashtable的性能相当

时间: 2024-08-30 09:29:40

测试HashTable、Collections.synchronizedMap和ConcurrentHashMap的性能的相关文章

Collections.synchronizedMap()与ConcurrentHashMap的区别

前面文章提到Collections.synchronizedMap()与ConcurrentHashM两者都提供了线程同步的功能.那两者的区别在哪呢?我们们先来看到代码例子.    下面代码实现一个线程对map进行写操作,另一个线程,读出并打印map数据. [java] view plain copy package test.map; import java.util.Collections; import java.util.HashMap; import java.util.Hashtab

ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点

ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含了一些主要集合类型 List 和 Map 的高性能的.线程安全的实现.在本月的 Java理论与实践中,BrianGoetz向您展示了用 ConcurrentHashMap 替换 Hashtable 或 synchronizedMap ,将有多少并发程序获益. 在Java类库中出现的第一个关联的集合类

ConcurrentHashMap Collections.synchronizedMap和Hashtable讨论

在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK1.0的一部分. Hashtable提供了一种易于使用的.线程安全的.关联的map功能,这当然也是方便的.然而,线程安全性是凭代价换来的――Hashtable的所有方法都是同步的.此时,无竞争的同步会导致可观的性能代价.Hashtable的后继者HashMap是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器Collections.synchronizedMap,解决了线程安全性问题.

What&#39;s the difference between ConcurrentHashMap and Collections.synchronizedMap(Map)?

来自:http://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-collections-synchronizedmap http://javarevisited.blogspot.hk/2011/04/difference-between-concurrenthashmap.html ╔═══════════════╦═══════════════════╦══════

Map m = Collections.synchronizedMap(new HashMap())

Collections.synchronizedMap(new HashMap())让你创建的new HashMap()支持多线程数据的同步.保证多线程访问数据的一致性 来源:http://www.blogjava.net/zlsunnan/archive/2006/07/02/56184.html 在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK 1.0的一部分.Hashtable提供了一种易于使用的.线程安全的.关联的map功能,这当然也是方便的.然而,线程安全性是凭

Java中SynchronizedMap与ConcurrentHashMap的对比

如何使用 概述 ConcurrentHashMap: 线程安全: 其将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段segment,而且每个小的片段segment上面都有锁存在,那么在插入元素的时候就要先找到应该插入到哪一个片段segment,然后再在这个片段上面进行插入,而且这里还需要获取segment锁(即锁分段技术): ConcurrentHashMap让锁的粒度更精细一些,并发性能更好: SynchronizedMap: 线程安全: 通过synchroni

iOS测试-如何指标量化app耗电量和性能XCTest Metrics

对于app端的专项测试,Android端我们可以用adb或者一些三方工具进行(例如itest)进行实时的性能监控,iOS端的话也可以用用一些三方的工具,但是需要嵌入到我们的项目当中,今天来介绍下Xcode11下的apple提供的基于XCTest对app耗电量和性能的全新框架. 资料来源:https://developer.apple.com/videos/play/wwdc2019/417/ app耗电量 app耗电量和它的性能体现是息息相关的,那么app中哪些性能项会影响耗电量呢? CPU m

Vector、HashTable、HashMap和ConcurrentHashMap

<java并发编程>的第二章2.1. 什么是线程安全性 讲到线程安全性的时候给出了一个例子考虑下面的代码片段,它迭代一个Vector 中的元素.尽管Vector 的所有方法都是同步的,但是在多线程的环境中不做额外的同步就使用这段代码仍然是不安全的,因为如果另一个线程恰好在错误的时间里删除了一个元素, 则get() 会抛出一个ArrayIndexOutOfBoundsException .Vector v = new Vector();// contains race conditions --

入门级----黑盒测试、白盒测试、手工测试、自动化测试、探索性测试、单元测试、性能测试、数据库性能、压力测试、安全性测试、SQL注入、缓冲区溢出、环境测试

黑盒测试 黑盒测试把产品软件当成是一个黑箱子,只有出口和入口,测试过程中只要知道往黑盒中输入什么东西,知道黑盒会出来什么结果就可以了,不需要了解黑箱子里面是如果做的. 即测试人员不用费神去理解软件里面的具体构成和原理,只要像用户一样看待产品就可以了. 例如银行转账功能,不需要知道转账的具体实现代码是怎样工作的,只需要把自己想象成各种类型的用户,模拟多种转账情况看系统是否能正常转账即可. 但是仅仅像用户一样去测试又是不够的.如果只做黑盒测试,必然是存在一定的风险的. 例如某个安全性较高的软件系统,