同步速度与正常速度

时间:2011-02-10 06:43:21

标签: java synchronization

我有一个为单个线程编写的类,没有同步的方法。

class MyClass implements MyInterface{
//interface implementation methods, not synchronized
}

但我们还需要该类的同步版本。所以我们创建了一个包装类,它实现了相同的接口,但是有一个构造函数,它接受一个MyClass实例。对synchronized类的方法的任何调用都被委托给MyClass的实例。这是我的同步课程。

class SynchronizedMyClass implements MyInterface{
//the constructor
public SynchronizedMyClass(MyInterface i/*this is actually an instance of MyClass*/)
//interface implementation methods; all synchronized; all delegated to the MyInterface instance
}

毕竟,我在两个课程中都进行了大量的测试。测试涉及读取日志文件和计算每行中的URL。问题是类的同步版本一直花费较少的时间进行解析。我只使用一个线程用于测试,因此没有死锁的机会,竞争条件等等。每个日志文件包含超过500万行,这意味着调用方法超过500万次。谁能解释为什么班级迁移的同步时间比正常时间少?

2 个答案:

答案 0 :(得分:5)

首先,您应该阅读有关使用Java制作基准的信息:How do I write a correct micro-benchmark in Java?

假设基准是好的,那么可能有以下几个原因:

  • Lock elision:如果JVM注意到只能从一个线程调用该方法,它可能会优化同步。

  • Lock coarsening:JVM可以将多个同步块组合到一个块中,从而提高性能。也许JVM能够更好地优化方法的同步版本。

  • Java中的非竞争同步块很快,因此可能很难注意到差异(尽管应该有一些开销)并且性能差异的原因可能是由其他原因造成的。存在争用时同步块变慢(即许多线程同时尝试访问它),在这种情况下,java.util.concurrent.locks和其他同步机制可能会更快。

原因也可能是别的。也许JVM以不同的方式优化方法。要查看实际发生的情况,请查看JIT生成的本机代码:How to see JIT-compiled code in JVM?

答案 1 :(得分:1)

正如已经指出的那样,微基准测试对Java来说并不是那么简单。

IMO没有理由担心同步本身的开销,即使在这种情况下,我也会将优化保存到您发现实际存在瓶颈的时候。

同步的有趣部分是您的代码在多线程环境中的工作方式。我一定会专注于确保在正确的位置正确使用同步。

坦率地说,需要同一类的完全同步和非同步版本听起来有点奇怪。

相关问题