How heavy are Java Monitors?

笑着哭i 提交于 2019-11-27 13:52:07

问题


Say I have an array of thousands of objects, and a small number of threads that might access each of the objects. I want to protect the access to one of the objects methods. Easiest way would be to declare that method as synchronized. However, that might result in creating thousands of monitors, whichever way they are implemented. If this were Win32, I'd never create thousands of kernel objects such as Mutex, but CRITICAL_SECTIONs might be plausible. I'm wondering what's the case in Java. Given the chance of contention is low, would the use of monitors impose more than the sheer amount of memory they require? How common a practice is it to use such low granularity synchronization in Java?

(There are obviously workarounds such as using a much smaller array of synchronization objects, which will be accessed using some hash. I'm not looking for a practical solution, I'm looking for an insight).


回答1:


You have already paid (most of, and in low-contention) the penalty for having the Monitors around by using Java... no sense not using them. Particularly in the low-contention case, they are very cheap (see Items 2.1, 2.2, 2.3 here and Item #1 here), and the JVM can optimize them away entirely for a number of cases. If you only use the object's monitor transiently, the JVM will make it "big enough" (meaning it begins as bit-flipping, might expand for simple contention cases to a stack-allocated atomic flag, and under persistent contention have a objectmonitor allocated for it; all of these will be unrolled back to the low-overhead case as contention abates) and reclaim the space later. To the extent that locking on these objects is the "right thing" on the application side, I'd say go for it.

However, there's a design smell here. Locking on so many objects doesn't sound great. Furthermore, if you have any sequential locking conditions, you're not going to be able to reason about potential deadlocks. I suggest you augment your question with more detail about the application, and we can ask whether locking on a large pool of objects is the Right Thing.

This presentation by Dave Dice gives some useful insight into how Java6 synchronization works, and this blog entry is a treasure trove of sync-on-Java information. If you really, really care about how "big" a full-on objectmonitor structure is (will come into play in the contended case), the code is here. The HotSpot internals wiki page also has some good in-depth information.




回答2:


Java mutexes are cheap enough that you can have hundreds of thousands of synchronized objects and not notice it.

In the uncontended case, a Java mutex consists of just 2 bits in the flags word. The JVM only associates a heavy-weight OS lock object with a Java mutex when the mutex is contended, and then releases the OS lock when the mutex has been exited by all threads.

An overview of how Java mutexes are implemented may be found in slides 9 to 23 of this presentation from Javaone 2006.


Note that the implementation and performance of mutexes is liable to depend on the vendor / release of Java that you are using, and the platform that you are running on.

  • In early Java releases, mutexes were significantly more expensive.
  • There may well have been advances since JavaOne 2006 paper ... eiether published or not.



回答3:


I think Collections.synchronizedCollection let one thread access the collection. However the problem of creating monitors exists.



来源:https://stackoverflow.com/questions/4068562/how-heavy-are-java-monitors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!