我已根据此https://dzone.com/articles/java-7-hashmap-vs编写了一个小测试来测试哪种方法表现更好
threadSafeMap2 = new HashMap<String, Integer>(2);
threadSafeMap2 = Collections.synchronizedMap(threadSafeMap2);
或
threadSafeMap3 = new ConcurrentHashMap<String, Integer>(2)
这是我的junit测试:
package com.bm.framework.concurrent;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
class WorkerThread implements Runnable
{
static final int WORKER_ITERATION_COUNT = 500000;
private Map<String, Integer> map = null;
public WorkerThread(Map<String, Integer> assignedMap)
{
this.map = assignedMap;
}
@Override
public void run()
{
for (int i=0; i < WORKER_ITERATION_COUNT; i++)
{
// Return 2 integers between 1-1000000 inclusive
Integer newInteger1 = (int) Math.ceil(Math.random() * 1000000);
Integer newInteger2 = (int) Math.ceil(Math.random() * 1000000);
// 1. Attempt to retrieve a random Integer element
Integer retrievedInteger = map.get(String.valueOf(newInteger1));
// 2. Attempt to insert a random Integer element
map.put(String.valueOf(newInteger2), newInteger2);
}
}
}
public class BmfThreadPoolTest
{
private static final int NB_THREADS = 3;
private static final int NB_TEST_ITERATIONS = 50;
private static Map<String, Integer> nonThreadSafeMap = null;
private static Map<String, Integer> threadSafeMap2 = null;
private static Map<String, Integer> threadSafeMap3 = null;
@Test
public void testMapPerformance() throws InterruptedException
{
// this is a test between two styles we see
// one is to use Collections.synchronizedMap()
// and the other one is to use directly ConcurrentHashMap which
// one is faster?
// Plain old HashMap (since JDK 1.2)
nonThreadSafeMap = new HashMap<String, Integer>(2);
// Fully synchronized HashMap
threadSafeMap2 = new HashMap<String, Integer>(2);
threadSafeMap2 = Collections.synchronizedMap(threadSafeMap2);
// ConcurrentHashMap (since JDK 1.5)
threadSafeMap3 = new ConcurrentHashMap<String, Integer>(2);
System.out.println("ConcurrentHashMap");
beginTest(threadSafeMap3);
// the second one is always performing poor no matter whether it is hashmap or concurrenthashmap why????
System.out.println("Collections.synchronizedMap()");
beginTest(threadSafeMap2);
}
private void beginTest(final Map<String, Integer> assignedMapForTest)
{
for (int i=0; i<NB_TEST_ITERATIONS; i++)
{
long timeBefore = System.currentTimeMillis();
long timeAfter = 0;
Float totalProcessingTime = null;
ExecutorService executor = Executors.newFixedThreadPool(NB_THREADS);
for (int j = 0; j < NB_THREADS; j++)
{
/** Assign the Map at your convenience **/
Runnable worker = new WorkerThread(assignedMapForTest);
executor.execute(worker);
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated())
{
}
timeAfter = System.currentTimeMillis();
totalProcessingTime = new Float( (float) (timeAfter - timeBefore) / (float) 1000);
System.out.println("All threads completed in "+totalProcessingTime+" seconds");
}
}
}
问题出在两个beginTest()调用之间,第二个调用总是表现不好,即如果我这样运行
beginTest(threadSafeMap3);
beginTest(threadSafeMap2);
最后一个需要更长的时间来完成指向ConcurrentHashMap更快的事实。如果我像这样交换订单
beginTest(threadSafeMap2);
beginTest(threadSafeMap3);
最后一个需要更长的时间来完成指向ConcurrentHashMap更慢的事实。 为什么我会根据测试中使用地图的顺序得到相互矛盾的结果?
如果我注释掉其中一个并在两个单独的运行中运行测试(一个用于同步哈希映射,一个用于ConcurrentHashMap),那么我总是以ConcurrentHashMap作为获胜者获得一致的结果。
答案 0 :(得分:2)
答案 1 :(得分:-1)