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

为什么所有Java对象都具有wait()和notify(),这会导致性能下降吗?

鲁望
2023-03-14
问题内容

每个Java
Object都有方法wait()notify()(以及其他变体)。我从来没有使用过这些,我怀疑很多其他人没有使用过。为什么这些是如此基本,以至于每个对象都必须拥有它们,并且拥有它们会对性能产生影响(大概在其中存储了某种状态)?

编辑
以强调该问题。如果我有一个List<Double>具有100,000个元素的元素,那么每个元素都Double具有从扩展的这些方法Object。但是似乎所有这些都不大可能必须了解管理的线程List

编辑
出色而有用的答案。@Jon有一个非常好的博客文章,使我的直觉更加具体。我也完全同意@Bob_Cross的意见,即在担心性能问题之前,应先显示性能问题。(作为成功语言的第n条定律,如果它对性能造成了很大的影响,那么Sun或某人将对其进行修复)。


问题答案:

那么,它确实意味着每个对象有 可能
有一个与之关联的监视器。使用相同的监视器synchronized。如果你有决定不服的,以便能够在任何对象上同步,然后wait()notify()不添加任何更多的每个对象的状态。JVM可能会延迟分配实际的监视器(我知道.NET会这样做),但是必须有一些存储空间可以用来说明哪个监视器与对象相关联。诚然,这可能是一个很小的数量(例如3个字节),由于其余对象开销的填充,实际上并不会节省任何内存-
您必须查看每个JVM如何处理内存来说当然。

请注意,仅拥有额外的 方法 不会影响性能(除了由于代码明显存在 于某处 而造成的影响很小)。并不是每个对象,甚至每个类型都有其自己的for
wait()和代码副本notify()。根据vtables的工作方式,每种类型都 可能 为每个继承的方法添加一个额外的vtable条目-
但这仍然仅基于每种类型,而不是基于每个对象。与用于实际对象本身的大量存储相比,这基本上会在噪声中丢失。

就我个人而言,我觉得.NET和Java都通过将监视器与每个对象相关联而犯了一个错误-
我宁愿拥有显式的同步对象。我在有关重新设计java.lang.Object /
System.Object的博客文章中对此进行了更多介绍。



 类似资料:
  • 问题内容: 似乎该线程都在其他线程调用或在此线程上唤醒。两者之间有什么区别吗? - 编辑 - 我知道一个是通知对象,另一个是中断线程。但是,这两种情况都会导致相同的结果,也就是说,该线程被唤醒,所以我想问的是这两种情况的后果是如何不同的。 问题答案: 当线程在某个监视器上调用notify时,它将唤醒在该监视器上等待的单个线程,但是 哪个 线程被唤醒由调度程序决定。(或者,一个线程可以调用notif

  • 问题内容: 使用ant,maven和buildr有什么意义?在eclipse或netbeans中使用using构建会无法正常工作吗?我很好奇扩展构建工具的目的和好处是什么。 问题答案: 依赖管理 :构建工具遵循组件模型,该组件模型提供有关在哪里寻找依赖的提示。在Eclipse / Netbeans中,您必须依赖JAR,并且您实际上并不知道此JAR是否已更新。使用这些构建工具,它们“知道”依赖项中的

  • 问题内容: 从MDN文档获取标准功能以及非标准属性 强烈建议不要更改对象的[[Prototype]],因为它非常慢且不可避免地会减慢现代JavaScript实现中的后续执行,无论如何实现。 使用添加属性是 在 添加成员函数JavaScript类的方式。然后如下图所示: 为什么不好?如果它的坏处不那么坏? 那么为什么会这样警告:它非常慢并且不可避免地会减慢现代JavaScript实现中的后续执行 。

  • 问题内容: 我有一个班级和年龄段。但是,当我更改对象的年龄时,该类的所有其他对象也会更改。 有人可以帮助解决这个问题吗? 问题答案: 静态变量 是 类变量, 因此从变量声明中删除为: 根据java docs: 在声明中具有static修饰符的字段称为静态字段或类变量。它们与类关联,而不与任何对象关联。该类的每个实例共享一个类变量,该变量位于内存中的一个固定位置。

  • 问题内容: 哈罗我已经整天调试了我的代码,但是我看不出哪里出了问题。 我在主线程上使用SerialPortEventListener,在工作线程中,我有一个客户端套接字与服务器通信。由于到达此工作线程之后,我仍然需要在主线程中完成一些总结工作,因此我想创建一个“伪线程”,在主线程中等待,直到从侦听器onEvent方法通知它为止。 但是这个伪线程似乎一直在等待。 我检查了锁定的线程,它们在Runna

  • 问题内容: 我是ORMLite的主要作者,它使用类上的Java注释来构建数据库模式。我们的程序包最大的启动性能问题是在Android 1.6下调用注释方法。直到3.0我都看到了相同的行为。 我们看到以下简单的注释代码 难以置信地 占用大量GC,这是一个实际的性能问题。在快速的Android设备上,对注释方法的1000次调用几乎耗时一秒。Macbook Pro上运行的相同代码可以同时进行2800万次