Need of an object in synchronised block - java

As per my understanding, if we add synchronized keyword in our code, whole block of code inside it will be locked for the other threads. In that case, why do we need to specify a particular object in synchronized keyword.
for eg. synchronized(lockObject). what is the use of lockObject here?

Let's say you have 2 resources you want to synchronize; the bathroom and the fridge.
You want people to be able to grab a snack from the fridge even if someone is using the bathroom, don't you?
So you use different locks on the fridge and on the bathroom.
In programming terms, that means that each independent resource can have it's own lockObject.
Note that a resource can have several methods that access them - all the accessors of the same resource should use the same lock! After all, if you have two doors into the bathroom it wouldn't do much good if you only locked one of them.

if we add synchronized keyword in our code, whole block of code inside it will be locked for the other threads.
Incorrect. synchronized involves a mechanism entirely separate from your block of code: acquiring and releasing a mutual exclusion lock. Java has the concept of synchronized blocks as a convenience to ensure proper release of a lock after it's acquired.
So, what actually happens is that your thread acquires the monitor associated with the instance given in the parentheses, then proceeds to execute the block of code, then releases the monitor. Meanwhile no other thread can acquire that particular monitor, but it can very well acquire any other object's monitor. If you don't take care to always have the same object involved in the synchronized block, you will get no mutual exclusion.

Related

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?
Seems you have one misunderstanding (dunno if it caused the wrong conclusion) that no one has pointed out. Anyway, a brief answer:
Intrinsic Lock: Just think it as, every object in JVM has internally a lock. synchronized keywords tries to acquire the lock of the target object. Whenever you synchronized (a) { doSomething; }, what actually happens is
the lock in a is acquired
code within the synchronized block is run (doSomething)
release the lock in a
and I wish you know
public synchronized void foo() {
doSomething;
}
is conceptually the same as
public void foo() {
synchronized(this) {
doSomething;
}
}
Ok, go back to your question, the biggest problem, imho, is :
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...
It is wrong. When you call a synchronized method, you are not get hold of the lock of the thread.
Instead, that thread will own the intrinsic lock of the object that is "owning" the method.
e.g. in thread1, you called a.foo(), and assume foo() is synchronized. thread1 is going to acquire the intrinsic lock of the object a referring.
Similarly, if AClass.bar() is called (and bar is synchronized and a static method), the intrinsic lock of AClass Class object will be acquired.
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
A lock can be held by only one thread at a time. That doesn't defeat the purpose; that is the purpose.
Threads mutually exclude each other from simultaneous action in critical sections by acquiring a lock, or mutex. This provides effective atomicity around a series of distinct actions, so that other threads never see intermediate states that might violate consistency guarantees.
Yes, you won't be able to call other synchronized method on the same object, because of the intrinsic lock. Which is at object level, only 1 thread will acquire it.
would I 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?
No. You can't call other synchronized method on same object for Object level lock and you can't call other static sysnchronized method on same class.
But it does not defeat the purpose of having synchronisation.
If you follow the other documentation page on synchronized methods:
Making these methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
If you allow two synchronized method to run in parallel. you will bound to get memory inconsistency errors on shared data.
On a different note, Lock provides better alternative synchronized construct.
Related SE question:
Synchronization vs Lock
It doesn't matter whether the synchronized method belongs to the same class or not, what matters is if the caller thread of the method acquires the lock or not, if it does, then it will be allowed enter the critical section because the lock is reentrant.
If it wasn't the case, then a recursive call would cause a deadlock,
fn(){
synchronized(mutex){ // the current thread has already acquired the mutex
fn();
}
}
fn here wont deadlock because the lock is re-entrant, ie ( the thread that's already acquiring the lock can enter and renter the critical section again as long as it is still acquired).
Locks can be divided in two classes - 'reentrant' and 'not reentrant'.
In Java 'synchronized', base implementation of interface Lock (class ReentrantLock), interface ReadWriteLock (class ReentrantReadWriteLock) - are reentrant.
Reentrancy means - one thread can again and again hold the lock.

"Monitor" in java threads

I have read different things in different blogs about monitors. So I'm a bit confused now.
As much as I understand, monitor is a somebody who would make sure that only one thread is executing the code in the critical section. So is it like if we have 3 synchronized methods/blocks then we would have 3 monitors to make sure that only one thread is in the critical section?
If the above is true then why it is said that in Java every object has a monitor associated with it? It should be every synchronized block is associated with a monitor.
What is a monitor?
A monitor is something a thread can grab and hold, preventing all other threads from grabbing that same monitor and forcing them to wait until the monitor is released. This is what a synchronized block does.
Where do these monitors come from in the first place?
The answer is: from any Java object. When you write:
Object foo = new Object();
synchronized (foo) {
System.out.println("Hello world.");
}
...what this means is: the current thread will first grab the monitor associated with the object stored in variable foo and hold it while it prints "Hello world", then releases it.
Why does every Java object have a monitor associated with it?
There is no technical reason for it to be that way. It was a design decision made in the early versions of Java and it's too late to change now (even though it is confusing at first and it does cause problems if people aren't careful).
When using synchronized with blocks, you specify an object to lock on. In that case, the monitor of that object is used for locking.
When using synchronized with methods, you don't specify an object to lock on, and instead this object is implied. Again, the monitor of this is used for locking.
So, objects have monitors, and synchronized methods/blocks do not have their own monitors, but instead they use the monitors of specific objects.
In the context of Java programming, the monitor is the intrinsic lock (where intrinsic means "built-in") on a Java object. For a thread to enter any synchronized instance method on an object it must first acquire the intrinsic lock on that object. For a thread to enter any synchronized static method on a class it must first acquire the intrinsic lock on that class.
This is how monitor is defined in the Java tutorial:
Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.")
There is a good reason that the monitor belongs to an object, and not to an individual block: the monitor is there to protect the state of the object. Objects should be designed to be cohesive, making it likely that instance variables will end up being referenced by multiple methods; the safe thing to do, in order to guarantee that the object is always in a consistent state, is to allow only one synchronized method on that object to execute at a time.
The term "monitor" comes from Concurrent Pascal. See Per Brinch Hansen's paper "Java's Insecure Parallelism", which argues that Java doesn't actually implement monitors:
Gosling (1996, p. 399) claims that Java uses monitors to synchronize threads. Unfortunately, a closer inspection reveals that Java does not support a monitor concept:
Unless they are declared as synchronized, Java class methods are unsynchronized.
Unless they are declared as private, Java class variables are public (within a package)
Another quote from the same paper:
The failure to give an adequate meaning to thread interaction is a very deep flaw of Java that vitiates the conceptual integrity of the monitor concept.

private lock object and intrinsic lock

When to prefer private lock object to synchronize a block over intrinsic lock(this)?
Please cite the upshots of both.
private lock object:-
Object lock =new Object();
synchronized(lock)
{ }
intrinsic lock(this):-
synchronized(this)
{ }
Using explicit lock objects can allow different methods to synchronize on different locks and avoid unnecessary contention. It also makes the lock more explicit, and can make it easier to search the code for blocks that use the lock.
You probably don't want to do either, however! Find the appropriate class in java.util.concurrent and use that instead. :)
A private lock can be useful if you are doing some kind of lock sharding, i.e., you need to only lock certain parts of your object while others can still be accessed by a different client.
One simple parallel to understand this concept is a table lock in a database: if you are modifying one table, you acquire the lock on that single table, not the whole database, so the rest of the tables can be modified by other clients. If you need to implement a similar logic but in a POJO you would use as many private locks as necessary.
One downside of this approach is that your class gets cluttered with a lot of objects. This might be indication that you need to refactor it in a more granular set of classes with a simpler locking strategy but it all depends on your design and implementation.
These are both using intrinsic locks. Your first example is using the intrinsic lock of lock, while the second is using the intrinsic lock of this. The question is whether or not this is really what you want to lock on, which it often isn't.
Consider the case, when you use synchronized(this) inside one of your methods. You have 2 objects of this class, and these objects reference some shared resource. If you lock on this then you will not have mutual exclusivity to that resource. You need to lock on some object that everything that can access the resource has access to.
Lock on this ONLY if the important resource is part of the class itself. Even then in some cases a lock object is better. Also, if there's several different resources in your class, that do not need to be mutually exclusive as a whole, but individually, then you need several lock objects.
The key is to really just know how synchronized works, and be mindful of what your code is actually doing
Actually, using either won't make any difference, it is more about choice/style, API writers will lock on the Object -either by synchronized(this) or explicit synchronized on any Object method-, or use an internal monitor depends on sharing a resource, you might not want API users to access your internal lock or you might want to give the choice to API users to share the Object intrinsic lock.
Either way none of those choices are wrong, it is more about the intention of such lock.
Read Java Concurrency in Practice, that will make you a master of concurrency and clarify many of those concepts, which sometimes are more related with the choice you make rather than correctness.
Each object has only one intrinsic lock.
With the synchronized keyword: if you call two synchronized methods from the same object from two different threads, even-thought one thread could run method one and the other thread could run method two, that will not happen because both methods share the same intrinsic lock (which belongs to the object). And according to that one thread will have to wait for the other thread to finish before it can acquire the intrinsic lock to run the other method.
But if you use multiple locks, you will make sure that only one thread can access method one at a time and that only one thread can access method two at a time. But you will allow that method one and method two can be accessed by one thread each at the same time and then reducing the time required for the operation.

Why can't I directly access (and lock) the implicit lock that Objects use for synchronized block

rephrased for clarity
I would like to be able to mix the use of the synchronized block with more explicit locking via calling lock and release methods directly when appropriate. Thus allowing me the syntaxtical sugar of using sychtronized(myObject) when I can get away with it, but also being able to call myObject.lock & myObject.unlock dierctly for those times when a synchronized block is not flexible enough to do what I need done.
I know that every single Object has, implicitly, a rentrant lock built into it which is used by the synchronized block. Effectively the the lock mthod is caled on the Objects internal reentrant lock every time one enters a sychronized block, and unlock is called on the same reentrant lock when you leave the synchronized block. I would seem as if it wouldn be easy enough to allow one the ability to manually lock/unlock this inplicit reentrant lock; thus allowing a mixing of synchronized blocks and explcit locking.
However, as far as I know there is no way to do this. And because of the way synchronized blocks work I don't believe there is a convenient way to mix them with explicit locking othewrise. It seems as if this would be a rather convenient, and easily added by expending the Object api to add lock/unlock methods.
The question I have is, why doesn't this exist? I'm certain there is a reason, but I don't know what it is. I thought the issue may be with encapsulation; same reason you don't want to do synchronize(this). However, if I am already calling sycnhronized(myObject) then by defination anyone who knows about myObject can likewise synchronize on it and cause a deadlock if done foolishly. The question of encapsulation comes down to who can access the object you synchronized on regardless of rather you use a sychtronized block or manually locked the object; at least as I see it. So is there some other advantage to not allowing one to manually lock an object?
The locks of a certain object is highly tied to the instance itself. The structure of the synchronized blocks and methods are very strict. If you, as a programmer, would have the possibility to interfere with the system (virtual machine), it could cause serious problems.
You could eventually release a lock that was created by a synchronized block
You create a lock that another synchronized block will release
You create more lock entries than exits
You create more lock exits than entries
There are even specific bytecodes defined for the lock and release operations. If you would have a "method" for this lock/unlock operation, it should be compiled to these bytecodes. So, it is really a low-level operation, and very much different from other Java object level implementations.
Synchronisation is a very strong contract. I think that the designers of the JLS did not want to allow the possibility to break this contract.
The Chapter 17 of the JLS describes more about the expected behaviour.

Difference between synchronized and re-entrant lock? [duplicate]

This question already has an answer here:
What's the difference in using ReentrentLock and Synchronized(object)? [duplicate]
(1 answer)
Closed 5 years ago.
I have used the synchronized keyword and re-entrant locks in Java, but I don't understand how they differ, or which is appropriate for a given situation.
How do I decide when should I use synchronized and when I should use re-entrant locks?
A ReentrantLock is:
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities.
Extended capabilities include:
The ability to have more than one condition variable per monitor. Monitors that use the synchronized keyword can only have one. This means reentrant locks support more than one wait()/notify() queue.
The ability to make the lock fair. Synchronized blocks are unfair.
"[fair] locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order."
The ability to check if the lock is being held.
The ability to get the list of threads waiting on the lock.
The disadvantages of reentrant locks are:
Need to add import statement.
Need to wrap lock acquisitions in a try/finally block. This makes it more ugly than the synchronized keyword.
The synchronized keyword can be put in method definitions which avoids the need for a block which reduces nesting.
Summary
The synchronized keyword is syntactically nicer, but the Reentrant lock has more features.
This site clearly mentioned difference between ReentrantLock and synchronized keyword in Java. I just copy and paste from there.
http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html
1) Another significant difference between ReentrantLock and synchronized keyword is fairness. synchronized keyword doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make ReentrantLock fair by specifying fairness property, while creating instance of ReentrantLock. Fairness property provides lock to longest waiting thread, in case of contention.
2) Second difference between synchronized and Reentrant lock is tryLock() method. ReentrantLock provides convenient tryLock() method, which acquires lock only if its available or not held by any other thread. This reduce blocking of thread waiting for lock in Java application.
3) One more worth noting difference between ReentrantLock and synchronized keyword in Java is, ability to interrupt Thread while waiting for Lock. In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock. Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.
4) ReentrantLock also provides convenient method to get List of all threads waiting for lock.
I have always thought of synchronization as "the hack of least resistance". It just works and most everyone understands how it works, but it has some weaknesses that could affect your design under heavy concurrency. Not least of which is any client effectively has direct access to your object's synchronization lock meaning if they grab it and hold it other clients can't. In other words, the locking implemented by default synchronization effectively "publishes" you object's internal locking mechanism. Yuk. Its like setting yourself up for self-inflicted denial-of-service.
If you make the reentrant lock internal to your class (or just don't use the synchronized but do something like synchronize on some internal object that you new up in your constructor everywhere that you want synchronization), you remove this side-effect of publishing your internal locking mechanism, with the added complexity of you having to remember where to apply this internal synchronization as your class evolves.

Categories

Resources