当前位置: 首页 > 面试题库 >

避免在Java中同步(this)?

明松
2023-03-14
问题内容

每当关于Java同步的问题浮出水面时,有些人就会很想指出synchronized(this)应该避免的事情。他们声称,取而代之的是,最好是锁定私有引用。

给出的一些原因是:

  • 一些邪恶的代码可能会窃取你的锁(非常流行,也有一个“偶然”的变体)
  • 同一类中的所有同步方法都使用完全相同的锁,这会降低吞吐量
  • 你(不必要地)暴露了太多信息

包括我在内的其他人则认为,这synchronized(this)是一个惯用语言(在Java库中也是如此),是安全且易于理解的。应当避免这种情况,因为你有一个错误,而且对多线程程序中正在发生的事情一无所知。换句话说:如果适用,请使用它。

我对看到一些真实的示例(没有foobar的东西)感兴趣,在这种情况下,避免锁定this也更可取synchronized(this)

因此:你是否应该始终避免synchronized(this)使用私有引用锁定并替换它?

一些进一步的信息(根据给出的答案进行更新):

  • 我们正在谈论实例同步
  • 的隐式(synchronized方法)和显式形式synchronized(this)都被考虑
  • 如果你引用Bloch或有关该主题的其他权威,请不要遗漏你不喜欢的部分(例如,Effective Java,Thread Safety上的项目:通常是实例本身的锁,但也有例外)。
  • 如果你需要锁定而不是synchronized(this)提供粒度,synchronized(this)则不适用,所以这不是问题

问题答案:

我将分别讨论每个要点。

  1. 一些邪恶的代码可能会窃取你的锁(非常流行,但也有“偶然的”变体)

我更担心意外。这意味着该用法this是你的类的公开接口的一部分,应进行记录。有时需要其他代码使用你的锁的能力。诸如此类的事情都是如此Collections.synchronizedMap(请参阅javadoc)。

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

这太过简单了。仅仅摆脱synchronized(this)将无法解决问题。正确同步吞吐量需要更多考虑。

  1. 你(不必要地)暴露了太多信息

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



 类似资料:
  • 下面的方法位于类中,后台线程每60秒调用一次。它将ping一个套接字,检查它是否处于活动状态,并将所有内容放在映射中。 另外,我在同一个类中有以下方法。方法将由多个读取线程(假设最多10个线程)同时调用,以获取下一个活动的套接字。 如果计时器线程在方法中的上工作,那么所有这10个线程都应该在其他活动套接字上工作(这10个线程中的每一个都在不同的活动套接字上工作) 和所有这10个线程应该始终在不同的

  • 问题内容: 我有以下(也许是常见的)问题,此刻绝对使我感到困惑: 有几个生成的事件对象扩展了抽象类,我想将它们划分为Session Bean,例如 但是将来可能会有两种以上的事件类型,因此if- else将会很长,甚至可能无法读取。另外,在这种情况下,我认为这并不是真正的“最佳实践”。 我可以在类型中添加一个抽象方法,并让它们自行划分,但随后我必须在每个实体中注入特定的Session Bean。

  • 问题内容: 具有“ instanceof”操作链被认为是“代码异味”。标准答案是“使用多态性”。在这种情况下我该怎么办? 基类有许多子类。他们都不在我的控制之下。类似的情况是Java类Integer,Double,BigDecimal等。 我确实可以控制等。 我不想使用几行代码就能完成的代码。(有时,我制作了一个HashMap将映射到的实例,将映射到的实例,等等。但是今天我想要一些更简单的方法。)

  • 如何预防 Java 中著名的 NullPointerException 异常?这是每个 Java 初学者迟早会问到的关键问题之一。而且中级和高级程序员也在时时刻刻规避这个错误。其是迄今为止 Java 以及很多其他编程语言中最流行的一种错误。 Null 引用的发明者 Tony Hoare 在 2009 年道歉,并称这种错误为他的十亿美元错误。 我将其称之为自己的十亿美元错误。它的发明是在1965 年

  • 问题内容: 建议在HTML页面中使用表格(现在已经有了CSS)? 表格有什么用途?表具有哪些CSS所没有的功能? 问题答案: 一点都不。但是将表格用于表格数据。只是不要将它们用于一般布局。 但是,如果您显示表格数据(例如结果或什至是表格),请继续使用表格!

  • 问题内容: 我是JavaEE的新手,并试图通过检查数据库来学习制作一个简单的登录页面。这是代码示例: 它应该容易受到SQL注入的侵害吧?我可以通过在ASP.NET中使用参数化查询来做到这一点,如下所示: 有没有办法像这样在Java中使用参数化查询?谁能以参数化形式使用该查询来避免SQL注入? 谢谢 问题答案: 是的,你可以做到这一点;例如: