繁体   English   中英

java:围绕相同的代码同步与更多同步

[英]java: one synchronized vs more synchronized around the same code

一个同步比很多同步更好吗?

synchronized(this)
{
   CODE1
   CODE2 // uncritically code, short duration
   CODE3
   CODE4 // uncritically code, short duration
   CODE5
}

VS

synchronized(this)
{
   CODE1
}

CODE2 // uncritically code, short duration

synchronized(this)
{
   CODE3
}

CODE4 // uncritically code, short duration

synchronized(this)
{
   CODE5
}

以下适用:同步块尽可能小,就像我在第二个示例中编码的那样。

但这在任何情况下都是正确的吗? 如果不严格的代码片段在持续时间很短的 enoguh 中,如果我不锁定解锁锁定解锁等,也许我的程序性能更高?

如果有助于性能,JVM 的优化器能够加入相邻的同步块,但它不能做相反的事情,因为拆分它会改变语义。

请参阅 Java SE 6 性能白皮书, 2.1.2 锁粗化

有一些锁定模式,其中释放锁定,然后在一段代码中重新获取,中间没有发生可观察的操作。 在热点中实现的锁粗化优化技术消除了在这些情况下的解锁和重新锁定操作[...]。 它基本上通过扩大现有的同步区域来减少同步工作量。

对 Java 6 的引用表明这甚至不是一个全新的功能
因此,如果您知道存在不重要的代码并且整个代码都在临时释放锁(这可能会导致其他线程改变其间的状态),然后使用多个同步块,告诉 JVM 和人类读者 CODE2 和CODE4 并不重要。

这遵循让运行时优化器做出正确权衡的典型模式,因为它比我们更了解实际情况,即硬件和实际应用程序行为。

你没有提供足够的信息来回答这个问题。

据推测,CODE1、CODE3 和 CODE5 访问与其他线程共享的数据,因为如果它们不这样做,那么使用synchronized将毫无意义。

那么,如果线程 B 在线程 A 执行了 CODE1 但尚未执行 CODE3 或 CODE5 之后尝试使用共享数据,会发生什么? 如果在线程 A 执行了 CODE1 和 CODE3 而不是 CODE5 之后线程 B 尝试使用共享数据会发生什么? 如果结果可能发生任何不好的事情,那么您需要在同一个同步块中执行所有三个代码,而且,无论线程 B 使用相同的共享数据做什么,它也必须在类似的synchronized(this)块。


如果 CODE1、CODE3 和 CODE5 彼此完全独立,那么我的直觉反应将是使用几个较小的synchronized块——尤其是如果五个 CODE 中的任何一个花费了大量时间。 我喜欢保持synchronized块尽可能短(时间)。

但是如果性能真的很关键,那么你应该衡量它并向自己证明哪个是更好的方法。

暂无
暂无

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

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