假设我有一个包含数千个对象的数组,以及可能访问每个对象的少量线程。我想保护对其中一种对象方法的访问。最简单的方法是将该方法声明为 synchronized
。但是,这可能会导致创建数以千计的监视器,无论它们是如何实现的。如果这是 Win32,我永远不会创建数以千计的内核对象,例如 Mutex,但 CRITICAL_SECTIONs 可能 是合理的。我想知道 Java 中的情况。考虑到争用的可能性很低,使用监视器是否会超出它们所需的内存量?在 Java 中使用这种低粒度同步的做法有多普遍?
(显然有一些变通方法,例如使用更小的同步对象数组,这些对象将使用一些哈希来访问。我不是在寻找实用的解决方案,而是在寻找洞察力)。
最佳答案
您已经为使用 Java 使用监视器而付出了(大部分,并且在低争用中)的代价……不使用它们是没有意义的。特别是在低竞争情况下,它们非常便宜(参见 Items 2.1, 2.2, 2.3 here 和 Item #1 here ),并且 JVM 可以针对许多情况完全优化它们。如果您只是短暂地使用对象的监视器,JVM 将使它“足够大”(这意味着它以位翻转开始,可能会针对简单的争用情况扩展为堆栈分配的原子标志,并且在持久争用下为分配对象监视器它;随着争用的减少,所有这些都将展开回低开销的情况)并在以后回收空间。就锁定这些对象在应用程序方面是“正确的事情”而言,我会说去做吧。
但是,这里有一种设计味道。锁定这么多对象听起来不太好。此外,如果您有任何顺序锁定条件,您将无法推断出潜在的死锁。我建议您用有关应用程序的更多详细信息来补充您的问题,我们可以询问锁定大型对象池是否正确。
这presentation by Dave Dice对 Java6 同步的工作原理提供了一些有用的见解,这 blog entry is a treasure trove of sync-on-Java information .如果您真的非常关心完整的对象监视器结构有多大(将在有争议的情况下发挥作用),code is here . HotSpot 内部维基页面也有一些 good in-depth information .
关于java - Java 监视器有多重?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4068562/