简体   繁体   English

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

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

is one synchronized better than a lot of synchronized?一个同步比很多同步更好吗?

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

VS VS

synchronized(this)
{
   CODE1
}

CODE2 // uncritically code, short duration

synchronized(this)
{
   CODE3
}

CODE4 // uncritically code, short duration

synchronized(this)
{
   CODE5
}

the following applies: the synchronized blocks so small as possible, like i coded in my secound example.以下适用:同步块尽可能小,就像我在第二个示例中编码的那样。

But is that right in any case?但这在任何情况下都是正确的吗? If the uncritcally code snippets a in the duration short enoguh, maybe my program is more performant if i dont lock unlock lock unlock and so on?如果不严格的代码片段在持续时间很短的 enoguh 中,如果我不锁定解锁锁定解锁等,也许我的程序性能更高?

The JVM's optimizer is capable of joining adjacent synchronized blocks if it helps performance, but it can't do the opposite, as splitting it would change the semantic.如果有助于性能,JVM 的优化器能够加入相邻的同步块,但它不能做相反的事情,因为拆分它会改变语义。

See the Java SE 6 Performance White Paper, 2.1.2 Lock coarsening请参阅 Java SE 6 性能白皮书, 2.1.2 锁粗化

There are some patterns of locking where a lock is released and then reacquired within a piece of code where no observable operations occur in between.有一些锁定模式,其中释放锁定,然后在一段代码中重新获取,中间没有发生可观察的操作。 The lock coarsening optimization technique implemented in hotspot eliminates the unlock and relock operations in those situations […].在热点中实现的锁粗化优化技术消除了在这些情况下的解锁和重新锁定操作[...]。 It basically reduces the amount of synchronization work by enlarging an existing synchronized region.它基本上通过扩大现有的同步区域来减少同步工作量。

the reference to Java 6 shows that this is not even a brand new feature对 Java 6 的引用表明这甚至不是一个全新的功能
So if you know that there's uncritical code and the entire code works with temporarily releasing the lock (which may have the state altered in-between by other threads), then use multiple synchronized blocks, to tell the JVM and the human readers that CODE2 and CODE4 are not critical.因此,如果您知道存在不重要的代码并且整个代码都在临时释放锁(这可能会导致其他线程改变其间的状态),然后使用多个同步块,告诉 JVM 和人类读者 CODE2 和CODE4 并不重要。

This follows the typical pattern of letting the runtime optimizer make the right trade-offs, as it knows more about the actual situation, ie hardware and actual application behavior, than us.这遵循让运行时优化器做出正确权衡的典型模式,因为它比我们更了解实际情况,即硬件和实际应用程序行为。

You have not given enough information to answer the question.你没有提供足够的信息来回答这个问题。

Presumably, CODE1, CODE3, and CODE5 access data that is shared with other threads because if they did not, then there would be no point in using synchronized .据推测,CODE1、CODE3 和 CODE5 访问与其他线程共享的数据,因为如果它们不这样做,那么使用synchronized将毫无意义。

So, what would happen if thread B tries to use the shared data after thread A has performed CODE1, but not yet performed CODE3 or CODE5?那么,如果线程 B 在线程 A 执行了 CODE1 但尚未执行 CODE3 或 CODE5 之后尝试使用共享数据,会发生什么? What would happen if thread B tries to use the shared data after thread A has performed CODE1 and CODE3, but not CODE5?如果在线程 A 执行了 CODE1 和 CODE3 而不是 CODE5 之后线程 B 尝试使用共享数据会发生什么? If any bad thing could happen as a result, then you need to perform all three of the CODEs in the same synchronized block, and also, whatever thread B is doing with that same shared data, it also must do it in a similar synchronized(this) block.如果结果可能发生任何不好的事情,那么您需要在同一个同步块中执行所有三个代码,而且,无论线程 B 使用相同的共享数据做什么,它也必须在类似的synchronized(this)块。


If CODE1, CODE3, and CODE5 are fully independent of each other, then my gut reaction would be to use several smaller synchronized blocks---especially so if any of the five CODEs takes any significant amount of time.如果 CODE1、CODE3 和 CODE5 彼此完全独立,那么我的直觉反应将是使用几个较小的synchronized块——尤其是如果五个 CODE 中的任何一个花费了大量时间。 I like to keep synchronized blocks as short (timewise) as possible.我喜欢保持synchronized块尽可能短(时间)。

But if the performance is really critical, then you ought to measure it and prove to yourself which is the better way.但是如果性能真的很关键,那么你应该衡量它并向自己证明哪个是更好的方法。

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

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