简体   繁体   中英

Java uses object as monitor, isn't that object too heavy weight?

I read this in Java language Spec 17.1:

"Each object in Java is associated with a monitor, which a thread can lock or unlock."

Why necessarily? Doesn't that make java object too heavy weight? I've no idea why a Object like, say, a string, should be naturally a monitor!

EDIT:

I think it over and yes, Java has a keyword synchronized , because EVERY object could have a synchronized method, so it's necessary to associate EVERY object a Monitor.

But still this seems not a very good solution, usually you need more that one mutex for one class, except for that pojo classes that's really very simple.

There is some truth in your assumptions, in the classical book "Java Concurrency in Practice" (written by the gurus Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea) they write:

The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects. In retrospect, this design decision was probably a bad one: not only can it be confusing, but it forces JVM implementors to make tradeoffs between object size and locking performance.

(chapter 2.4.: Guarding State with Locks)

Your fundamental problem is in assuming that every object has some sort of Monitor built into it, waiting for it to be used by some code. In reality, most objects are never used as a monitor, so the monitors don't have to be created until they are used. Rather than implementing this feature as every object having a private Monitor monitor field, think of it as being implemented as the JVM having a global HashMap<object, Monitor> monitors .

A possible implementation is this: Whenever a synchronized block is entered, the JVM looks up the synchronized object in the map ( monitors ). If it finds it, it gets the monitor to use. If it doesn't find it, it enters a critical section dedicated to the map. It then looks up the object again because another thread may have created it between the previous check and entering the critical section. If it's still not there, it creates the monitor for the synchronized object and leaves the critical section.

It's a pretty smart way to make virtually everything thread-safe. I think heavy weight is somewhat subjective; in Java, for example, the object only gains a notifiable wait queue, while specifying mutual exclusion is explicitly done with synchronize .

C# uses a similar method to enforce thread safety, so clearly MS also thought it was a pretty clever solution. The alternative is what? Hand-written semaphores and mutexes? In Java, that would be a nightmare, considering most production-level apps (ie servers, services, etc) have to be multi-threaded. Having the language do all that tough/boring stuff for you is kind of awesome.

Thread synchronization is necessary to ensure correct outcome as their may be racing condition.

Well, if it is not as heavy as a LCD or CRT monitor, it would be fine?

not that heavy in weight. objects are cheap.

I agree that the concept that any object can be a lock is quite confusing. many people thinks that synchronized(obj) protects the obj from being accessed concurrently. if we have separate locks from states, this misconception is less likely.

not text in java memory model shows any importance of using arbitrary object, or any object, as synchronization primitives. maybe it's economical design to use objects for this purpose.

it could as well use integers as locks. synchronized(493725) actually since each object is associated with an integer internally (its address), JVM probably does this. There's zero overhead for objects that are not being synchronized upon.

with java.util.concurrent classes, you don't ever need such synchronized(obj) any more, if you dislike it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM