ConcurrentHashMap性能测试


1、先测了一下多线程条件下hashmap,结果果然是不行啊,cpu在100%左右浮动,永远也执行不完put和get操作。

2、在能大概估计hashmap所要容纳的键值数量的情况下,可以直接用构造函数生成一定大小的map,这样避免在扩容的过程中不断的rehash成本。

3、具体代码见最后:i表示提交的线程数量,m表示每个线程执行的put和get次数。

1)如果只用单线程运行,线程内容修改如下:

public void run() {
		// TODO Auto-generated method stub
		for(int m=0;m<2000000;m++){
			String temp=":"+String.valueOf(m);
			map.put(temp, String.valueOf(m));
			map.get(temp);
			if(m%50000==0){
				System.out.println(m);
			}
		}
	}
这种场景下,在我的机器上一般打印到170万左右的时候就不再继续打印。这时候hashmap内总共的键值对有170万左右

2)当i=5000,m=1000时,线程池在完成了1600多个线程之后就再也无法完成剩下的线程,此时hashmap的键值对容量大概是160万左右。

同样的i=5000,m=1000时,如果把run函数里的key写成每个进程间都有重复的话(即把temp拼接的第一位去掉)就可以正常运行下去,结果的键值对容量是1000

3)当i=10000,m=100的时候,在我的机器上可以在2秒左右执行完成,结果的键值对数量是100万

      当i=100000,m=10的时候,在我的机器上也是2秒左右,结果的键值对数量也是100万

      当i=100000,m=20的时候,一般执行到90000多个线程的时候就执行不下去了。

      但如果把i改为20000,m=100的时候,则一般只执行到17000多个线程就执行不下去了,此时hashmap里键值对数量大概为170万左右


综上:

对concurrenthashmap而言,应付数多线程并发执行在效率上没什么太大的问题,两秒多一点时间可以执行读取操作各100万次无鸭梨;

只是在键值对数量超过一定数量的时候就会出现问题了,在我的机器上现在是170万左右。




代码如下:

public class HashMapTest {
	public static Map map=new ConcurrentHashMap(6000000); 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ThreadPoolExecutor te=(ThreadPoolExecutor)Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
		HashMapTest ht=new HashMapTest();
		long start=System.currentTimeMillis();
		for(int i=0;i<5000;i++){
			te.execute(ht.new Task(i));
		}
		while(te.getActiveCount()!=0){
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(te.getCompletedTaskCount());
		}
		te.shutdown();
		System.out.println("Time:"+(System.currentTimeMillis()-start));
	}
	
	class Task implements Runnable{
		public int i;
		public Task(int i){
			this.i=i;
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			for(int m=0;m<1000;m++){
				String temp=String.valueOf(i)+":"+String.valueOf(m);
				map.put(temp, String.valueOf(m));
				map.get(temp);
			}
			
		}
		
	}

}


你可能感兴趣的:(java)