【发布时间】:2011-11-08 12:23:08
【问题描述】:
我在从 hashmap 读取数据时面临可扩展性问题。我的机器有 32 个核心,每个核心有 2 个超线程(总共 64 个 CPU)和 64 GB RAM。 从 HashMap 读取数据并进行算术计算时,我发现从 16 个线程开始性能下降,但在仅执行算术运算时,它会按预期进行缩放。
请在下面找到测试结果:
从HashMap中读取并进行算术运算:
线程数 |所用时间(秒)=> 1 | 85, 2 | 93, 4 | 124, 8 | 147, 16 | 644
只执行算术运算:
线程数 |所用时间(秒)=> 1 | 25, 2 | 32, 4 | 35, 8 | 41, 16 | 65, 32 | 108, 40 | 112, 64 | 117, 100 | 158
同时添加代码块供参考:
import java.util.*;
import java.util.concurrent.*;
import java.lang.*;
public class StringCallable2
{
// private static final long size = 500000L;
private static final long size = 1000000L;
// private final static HashMap <Long,Long>map = new HashMap<Long, Long>();
// private static long[] array = new long[(int) size];
public static class StringGenCallable implements Callable
{
int count;
public StringGenCallable(int count)
{
this.count = count;
}
public Long call()
{
//Random rand = new Random();
// System.out.println("Thread " + count + " started test");
long sum = 20;
// do a CPU intensive arithmetic operation; no Input Output
// operations, object creations or floating point arithmetic
for (long i = 0; i < size; i++)
{
//int numNoRange = rand.nextInt((int)(size-1));
//long numNoRange = i;
// Long long1 = map.get((long)i);
//Long long1 = array[(int)i];
sum = i + 19 * sum;
}
// System.out.println("Finished " + count);
return sum;
}
}
public static void main(String args[])
{
try
{
System.out.println("Starting");
// for (long i = 0; i < size; i++)
// {
//array[(int)i] = System.currentTimeMillis();
// map.put(i, System.currentTimeMillis());
// }
int sizt = Integer.valueOf(args[0]);
long curtime = System.currentTimeMillis();
ExecutorService pool = Executors.newFixedThreadPool(sizt);
Set<Future<Integer>> set = new HashSet<Future<Integer>>();
for (int i = 0; i < sizt; i++)
{
Callable<Integer> callable = new StringGenCallable(i);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
long sum = 0;
for (Future<Integer> future : set)
{
future.get();
}
System.out.println("Number of threads : "+sizt);
long finsihtime = System.currentTimeMillis();
System.out.println("Total Time Taken : " + (finsihtime - curtime)+" ms");
pool.shutdown();
// System.exit(sum);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
catch (Error e) {
// TODO: handle exception
e.printStackTrace();
}
catch (Throwable e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
【问题讨论】:
-
哎呀。你忘记了问题。
-
这里的问题是什么?众所周知,锁争用会损害可伸缩性。无论如何,在您的情况下,您可以尝试
ConcurrentHashMap,它针对多线程使用进行了优化。 -
如果你用的是java5+,那就试试java.util.ConcurrentHashMap,这个类比较适合
标签: java multithreading