在java中使用多线程时性能降低
我是多线程新手,我必须使用多线程来编写程序以提高效率。在我第一次尝试时,我写的东西产生了相反的结果。以下是我写的:在java中使用多线程时性能降低,java,multithreading,concurrency,Java,Multithreading,Concurrency,我是多线程新手,我必须使用多线程来编写程序以提高效率。在我第一次尝试时,我写的东西产生了相反的结果。以下是我写的: class ThreadImpl implements Callable<ArrayList<Integer>> { //Bloom filter instance for one of the table BloomFilter<Integer> bloomFilterInstance = null; // Data
class ThreadImpl implements Callable<ArrayList<Integer>> {
//Bloom filter instance for one of the table
BloomFilter<Integer> bloomFilterInstance = null;
// Data member for complete data access.
ArrayList< ArrayList<UserBean> > data = null;
// Store the result of the testing
ArrayList<Integer> result = null;
int tableNo;
public ThreadImpl(BloomFilter<Integer> bloomFilterInstance,
ArrayList< ArrayList<UserBean> > data, int tableNo) {
this.bloomFilterInstance = bloomFilterInstance;
this.data = data;
result = new ArrayList<Integer>(this.data.size());
this.tableNo = tableNo;
}
public ArrayList<Integer> call() {
int[] tempResult = new int[this.data.size()];
for(int i=0; i<data.size() ;++i) {
tempResult[i] = 0;
}
ArrayList<UserBean> chkDataSet = null;
for(int i=0; i<this.data.size(); ++i) {
if(i==tableNo) {
//do nothing;
} else {
chkDataSet = new ArrayList<UserBean> (data.get(i));
for(UserBean toChk: chkDataSet) {
if(bloomFilterInstance.contains(toChk.getUserId())) {
++tempResult[i];
}
}
}
this.result.add(new Integer(tempResult[i]));
}
return result;
}
}
我和jprofiler做了分析
!![这里]:(http://tinypic.com/r/wh1v8p/6)
是cpu线程的快照,其中红色表示阻塞,绿色表示可运行,黄色表示等待。我的问题是线程一次运行一个,我不知道为什么
注意:我知道这不是线程安全的,但我知道我现在只做读取操作,只想分析可以实现的原始性能增益,稍后我将实现一个更好的版本。该进程看起来CPU受限。(无I/O、数据库调用、网络调用等)我可以想到两种解释:
我最初的建议是分析你的代码,看看这是否提供了一些见解
看看你衡量绩效的方式,确保你看到的不仅仅是一些标杆产品;e、 g.JVM预热效应。我想到了几种可能性:
的实现(未给出)中正在进行一些同步bloomFilterInstance
- 存在大量内存分配,例如,当创建
时,使用chkDataSet
而不是新整数
,这似乎是Integer.valueOf
数组列表的不必要副本。您可能会遇到内存分配的开销
- 您可能受到CPU的限制(如果
的开销很大),线程只是为CPU阻塞,而不是执行bloomFilterInstance#contains
探查器可能有助于揭示实际问题。bloomFilterInstance的特征是什么?有没有可能是同步的?没有,它没有使用同步块你使用了多少线程?显示启动线程的代码。添加了创建线程的代码。添加了分析信息我有2个内核。您是否需要明确指示jvm使用2个内核??整个方法用了6112毫秒(带线程)和5334毫秒(不带多线程)。默认情况下,它应该同时使用两个内核。您能检查一下我所做的分析吗?它清楚地表明,任何时候都没有两个线程并行运行,这就是性能下降的原因。请给出一些原因,我完全不明白这一点:在程序执行的前三分之二时间里根本没有线程。最后三分之一,两个核心都在使用。您不会看到所有5个内核同时运行,因为您只有两个内核。这意味着他们必须换掉(这并不能让事情变得更快),但要回到大部分时间——前二十秒。那里发生了什么事,花了这么长时间?添加一些计时语句或类似的语句,以查看哪个方法调用占用了所有的时间。
class MultithreadedVrsion {
public static void main(String[] args) {
if(args.length > 1) {
ExecutorService es = Executors.newFixedThreadPool(noOfTables);
List<Callable<ArrayList<Integer>>> threadedBloom = new ArrayList<Callable<ArrayList<Integer>>>(noOfTables);
for (int i=0; i<noOfTables; ++i) {
threadedBloom.add(new ThreadImpl(eval.bloomFilter.get(i),
eval.data, i));
}
try {
List<Future<ArrayList<Integer>>> answers = es.invokeAll(threadedBloom);
long endTime = System.currentTimeMillis();
System.out.println("using more than one thread for bloom filters: " + (endTime - startTime) + " milliseconds");
System.out.println("**Printing the results**");
for(Future<ArrayList<Integer>> element: answers) {
ArrayList<Integer> arrInt = element.get();
for(Integer i: arrInt) {
System.out.print(i.intValue());
System.out.print("\t");
}
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}