繁体   English   中英

同步代码比非同步代码执行得更快

[英]Synchronized code performs faster than unsynchronized one

我出来了这个惊人的结果,我绝对不知道原因:我有两种方法缩写为:

private static final ConcurrentHashMap<Double,Boolean> mapBoolean = 
        new ConcurrentHashMap<Double, Boolean>();
private static final ConcurrentHashMap<Double,LinkedBlockingQueue<Runnable>> map
        = new ConcurrentHashMap<Double, LinkedBlockingQueue<Runnable>>();


protected static <T> Future<T> execute(final Double id, Callable<T> call){
// where id is the ID number of each thread
synchronized(id)
{
   mapBoolean.get();// then do something with the result
   map.get();//the do somethign with the result
}
}

protected static <T> Future<T> executeLoosely(final Double id, Callable<T> call){

 mapBoolean.get();// then do something with the result
 map.get();//the do somethign with the result

 }

}

在使用超过500个线程进行性能分析,并且每个线程分别调用上述每个方法400次时,我发现execute(..)执行至少比executeLoosely(..)好500倍,这很奇怪,因为executeLoosely不同步,因此更多线程可以同时处理代码。

任何原因?

在我假设没有500个核心的机器上使用500个线程的开销,使用大约100-1000x的任务,只要在Map上执行查找以执行JVM可以检测到的代码就没有做任何事情,是可能产生随机结果。 ;)

您可能遇到的另一个问题是,使用synchronized执行更快的测试可以从使用synchronized中受益,因为它会偏向对一个线程的访问。 即它将您的多线程测试变回单线程测试,这是最快的。

您应该将您获得的时间与执行循环的单个线程进行比较。 如果这更快(我相信它会),那么它不是一个有用的多线程测试。

我的猜测是你在非同步代码之后运行同步代码。 即JVM已经预热了一点。 交换执行这些测试的顺序并多次运行它们会得到不同的结果。

在非同步场景中:1)等待获取地图段上的锁定,锁定,对地图执行操作,解锁,等待获取其他地图的某个段的锁定,锁定,在其他地图上执行操作,开锁。 段级锁定仅在并发写入段的情况下执行,在您的示例中看起来不是这种情况。

在同步方案中:1)等待锁定,执行两个操作,解锁。

上下文切换所需的时间会产生影响吗? 运行测试的机器有多少个核心? 地图是如何构建的,同样的键?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM