Swapnil Swapnil - 5 months ago 30
Java Question

What does intrinsic lock actually mean for a Java class?

In order to properly understand the issues and solutions for concurrency in Java, I was going through the official Java tutorial. In one of the pages they defined Intrinsic Locks and Synchronization link. In this page, they say that:


As long as a thread owns an intrinsic lock, no other thread can
acquire the same lock. The other thread will block when it attempts to
acquire the lock.


Also, they mention in the section Locks In Synchronized Methods that:


When a thread invokes a synchronized method, it automatically acquires
the intrinsic lock for that method's object and releases it when the
method returns. The lock release occurs even if the return was caused
by an uncaught exception.


For me this means that once I call a synchronized method from one of the threads, I will have hold of the intrinsic lock of the thread and since


Intrinsic locks play a role in both aspects of synchronization:
enforcing exclusive access to an object's state and establishing
happens-before relationships that are essential to visibility.


would another thread be unable to call another synchronized method of the same class? If yes, then the whole purpose of having synchronized methods is defeated. Isn't it?

Answer

So just to repeat my comment above as an answer. Intrinsic locking means that you don't have to create an object to synchronize your methods on. In comparison you can use an extrinsic lock by calling synchronized(myLock) {...}.

This is an excerpt from the book Java concurrency in practice: "The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects"

The book also says:

There is no inherent relationship between an object's intrinsic lock and its state; an object's fields need not be guarded by its intrinsic lock, though this is a perfectly valid locking convention that is used by many classes. Acquiring the lock associated with an object does not prevent other threads from accessing that objectthe only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock. The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects. [9] It is up to you to construct locking protocols or synchronization policies that let you access shared state safely, and to use them consistently throughout your program.

But in the footnote it says:

[9] 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.

And to answer your last questions: you won't be able to call the synchronized methods from another thread, but you can keep entering from the same thread (intrinsic locks are re-entrant). So you have to imagine locking in this case as serializing method access from different caller threads.

If you use locking improperly and then you introduce liveness hazards, then yes it is defeated. That's why you have to make sure that your concurrent threads are not contending with each other too hard.

As Brian Goetz puts in this blog entry:

In tuning an application's use of synchronization, then, we should try hard to reduce the amount of actual contention, rather than simply try to avoid using synchronization at all