java - Java 监视器有多重?

标签 java performance synchronization monitor

假设我有一个包含数千个对象的数组,以及可能访问每个对象的少量线程。我想保护对其中一种对象方法的访问。最简单的方法是将该方法声明为 synchronized。但是,这可能会导致创建数以千计的监视器,无论它们是如何实现的。如果这是 Win32,我永远不会创建数以千计的内核对象,例如 Mutex,但 CRITICAL_SECTIONs 可能 是合理的。我想知道 Java 中的情况。考虑到争用的可能性很低,使用监视器是否会超出它们所需的内存量?在 Java 中使用这种低粒度同步的做法有多普遍?

(显然有一些变通方法,例如使用更小的同步对象数组,这些对象将使用一些哈希来访问。我不是在寻找实用的解决方案,而是在寻找洞察力)。

最佳答案

您已经为使用 Java 使用监视器而付出了(大部分,并且在低争用中)的代价……不使用它们是没有意义的。特别是在低竞争情况下,它们非常便宜(参见 Items 2.1, 2.2, 2.3 hereItem #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/

相关文章:

java - 什么更快 - 将数据存储在列表中或数据库中? (安卓)

r - 更快的替代 `range(which(..))`

java - 在一个线程添加项目而一个线程删除项目时同步最大值

multithreading - 这会使对象线程安全吗?

java - 在 terracotta jobstore 中运行时,Quartz JobExecutionContext 不会持续存在

java - Spring-Boot - 只有对象的某些变量是绑定(bind)的

java - JKeyListener 字符/自动完成

performance - 在不使用第三个变量的情况下交换两个变量是否有意义?

c - 在c中用信号量同步两个子进程

java - 在 Java 中将文本文件转换为 JSON