在Java中避免同步(this)? [英] Avoid synchronized(this) in Java?

查看:142
本文介绍了在Java中避免同步(this)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当在SO上弹出一个关于Java同步的问题时,有些人非常渴望指出应该避免 synchronized(this)。相反,他们声称,首选锁定私人参考。

Whenever a question pops up on SO about Java synchronization, some people are very eager to point out that synchronized(this) should be avoided. Instead, they claim, a lock on a private reference is to be preferred.

一些给定的原因是:

  • some evil code may steal your lock (very popular this one, also has an "accidentally" variant)
  • all synchronized methods within the same class use the exact same lock, which reduces throughput
  • you are (unnecessarily) exposing too much information

其他人,包括我在内,认为已同步(这个)是一个被大量使用的习惯用法(也在Java库中),是安全且易于理解的。不应该避免它,因为你有一个错误,你不知道多线程程序中发生了什么。换句话说:如果适用,则使用它。

Other people, including me, argue that synchronized(this) is an idiom that is used a lot (also in Java libraries), is safe and well understood. It should not be avoided because you have a bug and you don't have a clue of what is going on in your multithreaded program. In other words: if it is applicable, then use it.

我有兴趣看到一些现实世界的例子(没有foobar的东西)避免锁定这个最好是 synchronized(this)也可以完成这项工作。

I am interested in seeing some real-world examples (no foobar stuff) where avoiding a lock on this is preferable when synchronized(this) would also do the job.

因此:你应该总是避免 synchronized(this)并将其替换为私人引用上的锁吗?

Therefore: should you always avoid synchronized(this) and replace it with a lock on a private reference?

更多信息(根据答案更新):

Some further info (updated as answers are given):


  • 我们讨论的是实例同步

  • 隐式( synchronized 方法)和显式形式 synchronized (这)被认为是

  • 如果你引用Bloch或其他有关主题的权威,不要遗漏你不喜欢的部分(例如Effective Java) ,线程安全项目:通常它是实例本身的锁定,但也有例外。)

  • 如果您需要锁定o的粒度o比 synchronized(this)提供,然后 synchronized(this)不适用,这不是问题

  • we are talking about instance synchronization
  • both implicit (synchronized methods) and explicit form of synchronized(this) are considered
  • if you quote Bloch or other authorities on the subject, don't leave out the parts you don't like (e.g. Effective Java, item on Thread Safety: Typically it is the lock on the instance itself, but there are exceptions.)
  • if you need granularity in your locking other than synchronized(this) provides, then synchronized(this) is not applicable so that's not the issue

推荐答案

我将分别涵盖每一点。



一些邪恶的代码可能会窃取你的锁(非常受欢迎的这个,也有一个
意外变种)

Some evil code may steal your lock (very popular this one, also has an "accidentally" variant)

我更担心意外。它相当于使用这个是你的类暴露界面的一部分,应该记录在案。有时需要其他代码使用锁的能力。这类似于 Collections.synchronizedMap (参见javadoc)。

I'm more worried about accidentally. What it amounts to is that this use of this is part of your class' exposed interface, and should be documented. Sometimes the ability of other code to use your lock is desired. This is true of things like Collections.synchronizedMap (see the javadoc).


同一类中的所有同步方法使用完全相同的
锁定,这会降低吞吐量

All synchronized methods within the same class use the exact same lock, which reduces throughput

这过于简单化思维;只是摆脱 synchronized(this)将无法解决问题。适当的吞吐量同步需要更多考虑。

This is overly simplistic thinking; just getting rid of synchronized(this) won't solve the problem. Proper synchronization for throughput will take more thought.


您(不必要地)暴露了太多信息

You are (unnecessarily) exposing too much information

这是#1的变体。使用 synchronized(this)是您界面的一部分。如果您不希望/需要暴露,请不要这样做。

This is a variant of #1. Use of synchronized(this) is part of your interface. If you don't want/need this exposed, don't do it.

这篇关于在Java中避免同步(this)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆