我正在尝试测试同步对象的多线程性能。但是,对于1个线程或16个线程,执行时间是相同的。
剩下的代码在这里。https://codeshare.io/5oj6ng
public void run() {
start = new Date().getTime();
System.out.println(start);
while (threadlist.size() < 9000) { //16 or more
// try{Thread.sleep(100);}catch (Exception f){}
Thread t = new Thread(new Runnable() {
public void run() {
while (add(1,3) < 1000000);
end = new Date().getTime();
System.out.println((end-start));
}
});
threadlist.add(t);
while( threadlist.iterator().hasNext()){
threadlist.iterator().next().start();
try{threadlist.iterator().next().join();}catch (Exception a){}
}
}
}
2条答案
按热度按时间gzjq41n41#
你的代码有一些问题。第一:
这些线程从未停止工作,我建议重写您的逻辑:
你启动线程,但从不调用
join
,最终你需要这样做。您只创建了1个线程,而不是您想要的16个线程:
你想要什么
最后,不要期望此代码有任何性能提升,因为您正在对象上同步:
所以基本上你的
add
方法是按顺序运行的,而不是并行运行的,因为线程将等待synchronized(this),并且只在synchronized语句 Package 的代码块中调用run-on。试着通过添加
start = new Date().getTime();
在平行区域之前,以及end = new Date().getTime();
之后。您只需编写代码即可:
6vl6ewon2#
自从@dreamcrash回复后,您已经显著地更新了代码。
当前版本存在以下问题:
这将启动一个线程,然后将立即坐在周围,旋转它的拇指,直到该线程完成它的工作,然后将启动另一个线程。因此,一次活动线程不超过1个。
catch (Exception a){}
你在学习/调试,你这么做?哦,亲爱的。不要。永远不要写这样的块。更新ide或肌肉内存:正确的“我现在不想考虑异常”代码是catch (Exception a) { throw new RuntimeException("Unhandled", a);}
. 要说清楚,这不是问题所在,但这是一个非常坏的习惯,它需要被唤醒。synchronized (this) {
我真的怀疑,如果你修复'加入'的问题,我前面提到这将永远运行更快。这个同步的调用很重要,但是它也会造成太多的阻塞,以至于您可能看不到任何实际的好处。更一般地说,您试图加速的计算涉及一个累加器。
累加器是“并行化在这里是完全不可能的,它是无望的”的另一个词。
如果您想并行化算法,那么它不能包含累加器,这就是多线程(至少,如果多线程的目的是加快速度的话)正在做的事情。这个算法在线程中不能再快了。句号。
通常可以重写算法以停止依赖累加器。但这显然是一个看效果的练习,所以,找点别的,真的。在整个计算过程中不要只锁定一个对象:只有一个线程在实际工作,其他所有线程都在等待。