java:围绕同一代码进行一次同步与多次同步

java:围绕同一代码进行一次同步与多次同步,java,concurrency,synchronized,Java,Concurrency,Synchronized,一次同步比多次同步好吗 synchronized(this) { CODE1 CODE2 // uncritically code, short duration CODE3 CODE4 // uncritically code, short duration CODE5 } VS 以下内容适用:同步块尽可能小,就像我在secound示例中编码的那样 但无论如何,这是正确的吗? 如果在很短的enoguh持续时间内,不加加密的代码片段a,那么我的程序的性能可能会更高

一次同步比多次同步好吗

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

以下内容适用:同步块尽可能小,就像我在secound示例中编码的那样

但无论如何,这是正确的吗?
如果在很短的enoguh持续时间内,不加加密的代码片段a,那么我的程序的性能可能会更高,如果我不加锁等等?

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

请参阅Java SE 6性能白皮书

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

对Java 6的引用表明,这甚至不是一个全新的特性
因此,如果您知道存在不关键的代码,并且整个代码都可以临时释放锁(这可能会让其他线程在其间改变状态),那么请使用多个同步块,告诉JVM和人类读者代码2和代码4不是关键的


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

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

据推测,CODE1、CODE3和CODE5访问与其他线程共享的数据,因为如果它们不访问,那么使用
synchronized
就没有意义了

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


如果CODE1、CODE3和CODE5彼此完全独立,那么我的直觉反应就是使用几个较小的
同步的
块——特别是如果五个代码中的任何一个都需要花费大量时间的话。我喜欢保持
同步
块尽可能短(按时间)


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

如果不对具体案例进行基准测试,你永远不会知道。这实际上是特定于上下文的。如果CODE4与CODE1或CODE2有某种关联呢?整个prorgram的性能增益/损耗真的很重要吗?不加批判的代码意味着,code4与其他东西无关。
synchronized(this)
{
   CODE1
}

CODE2 // uncritically code, short duration

synchronized(this)
{
   CODE3
}

CODE4 // uncritically code, short duration

synchronized(this)
{
   CODE5
}