Understanding and confusion over synchronization in java - java

Suppose we have
class A {
synchronized void m1() {
}
synchronized void m2() {
}
void m3() {
}
static void m6() {
synchronized(this){
}
}
}
and two instances of class A a1&a2.
Now if thread t1 with instance a1 call the method m1,there is only restriction that thread t2 with instance a1 can't execute method m1 untill t1 finishes the execution of m1. And t2 with instance a2 can execute m1().
Now my doubt is Can thread t1 with a1 can execute other method's(except m1) parallaly while executing m1?
what's difference b/w synchronized block and synchronized method? Is the difference only that the block have lesser scope for synchronization so it is efficient?
I read an article stating "Synchronized block can throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null".
We always use "this" as parameter to synchronized block, so there is only and always case using synchronized block inside a static method.Beacuse we don't need an object instantian to execute static method.
Where did i misunderstood it?

Now if thread t1 with instance a1 call the method m1,there is only
restriction that thread t2 with instance a1 can't execute method m1
untill t1 finishes the execution of m1. And t2 with instance a2 can
execute m1().
This is correct. Since both threads are synchronized on the same instance, the first Thread gets to execute and the second Thread gets to wait.
Now my doubt is Can thread t1 with a1 can execute other
method's(except m1) parallaly while executing m1?
Yes, this is known as reentrant synchronization. Take a look at the end of this tutorial.
what's difference b/w synchronized block and synchronized method? Is
the difference only that the block have lesser scope for
synchronization so it is efficient?
A synchronized block can be used on any instance. A synchronized method synchronizes on this implicitly. Try to use synchronized blocks as often as possible only around the actual critical section.
I raed a article stating "Synchronized block can throw
java.lang.NullPointerException if expression provided to block as
parameter evaluates to null".
The following
synchronized(null) {...}
would throw NullPointerException.

for example, synchronized(this){...} will be run only around the actual critical section, and only on the current instance but synchronized(otherInstance){...} will works with other instance independently of current instance

I think yes.
About synchronize on this ,-if you synchronize on 'this' or indeed any publicly visible object for the internal (or even external) logic of a particular class, you run the risk that something outside the class may "interfere" with things by holding on to the lock. So... whenever you are deciding on the locking mechanism for a particular case, you need to weigh things up and make it clear in your API what that object's locking policy is.

Related

Reentrancy in synchronized methods

Are synchronized methods reentrant?
I have this code:
public class Main {
synchronized void m1() {
//some code
m2();
//some code
}
synchronized void m2(){
//some code
}
}
Say two threads (Thread A and Thread B) try to access m1() at the same time. Thread A takes lock first. After some time Thread A calls m2(), which is also synchronized on same object.
As I don't want to make any guesses can someone tell me this: Is there any guarantee what will happen when Thread A calls m2()? I mean once Thread A calls m2(), does it 'leave lock' at all? Because technically it left method's frame, so will it leave lock as well?
[EDIT]: Does Thread A get to run m2() every time once it calls it? Or does it leave lock so both Thread A and Thread B would race for their goals?
In Java locks are reentrant. If Thread A holds the lock, then it can start executing method m1. Eventually it will invoke method m2, since Thread A already holds the lock, it does not have to reacquire the lock again to execute method m2. Internally the lock keeps the owner field to track this. Even if the lock is already held, since the caller of m2 is the owner of the lock, the access is granted. This design strategy prevents deadlocks.

Can two different objects like o1 and 02 of same class with different thead like t1 and t2 can they execute synchronized method at the same time

Assuming I have two different objects of same class, do they will able to execute the same synchronized method at the same time because the lock is on the object ant not on the method.
Example:
MyCLass cc= new MyCLass();
MyCLass cc1= new MyCLass();
Now create two thread
t1 --- it will call cc.meth
t2--it will call cc1.meth
// in this case t1 thread get lock on object cc and t2 thread get lock on object cc1.. it will work
synchronized meth(){
}
is it correct?
I think your question is answered here https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html, that tell that just one instance of the same class is locked while executing a synchronized method, obviously even if executed by a thread.
You are right. Synchronized methods lock their instance, not the class nor the method (for synchronized static methods, see below...).
So, on a given instance, only one thread can be inside any of its synchronized methods, but that does not block threads working with other instances of the same class.
Synchronized static methods lock the class (they don't have a this instance), so of all threads only one at a time can be executing inside a synchronized static method of the given class.
And if you need some other locking scheme, you can use a synchronized(someObject) { ... } block, which synchronizes on someObject, and then you are free to select the object that represents the mutual-exclusion group.
So, a synchronized method A.b() is equivalent to synchronized(this) {...} or (in the static case) synchronized(A.class) {...}.
synchronized implemented by monitorenter. You can see it in your byte code. monitorenter use the object monitor - the monitor of the instance of the class (not the class itself). So it is the expected behavior. If two threads try to execute synchronized methods of two different instances at the same time, both should not be blocked.
Actually it is better to avoid synchronized if the objects are not shared because synchronized is not good for performance. You should start thinking about synchronized only when you know that the object will be shared by more than one thread, which is not your case.
EDIT:
More simple explanation is that this code:
public synchronized void meth() {
...
}
equivalent to:
public void meth() {
synchronized (this){
...
}
}

How multiple synchronized key words work in a single class?

package anonymous;
public class A {
public static int counter=0;
public static void main(String[] args) {
synchronized (args) {
//some logic
}
synchronized (args) {
//some logic
}
}
}
Let say one thread is executing in one synchronized block. Can another thread acquire lock on other synchronized block?
What will happen if a method call happened within a synchronized block to a nonsynchronized method? will that method be thread safe?
What if we try to access a static variable from a synchronized instance method?? At a time each thread accessing a synchronized block in each instance will try to modify the static variable. Is n't it? In this case how we can have thread safety??
Can another thread acquire lock on other synchronized block?
No, only one synchronized method at a time can run. A call to the other synchronized method will have to wait until the first method is done. This is described in the Java tutorials:
...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.
What will happen if a method call happened within a synchronized block to a nonsynchronized method? will that method be thread safe?
If the non-synchronized method is only called from synchronized methods belonging to this Object, then it can be considered thread-safe, since only one thread can execute one of the calling (synchronized) methods at a time.
Note that, as #Ordous points out below, static synchronized methods lock on the class, and non-static synchronized methods lock on the instance. Therefore a non-static method can interleave with a static method belonging to the class in question.
No, any other thread will not be able execute another block which acquires lock on the same object in your case args.
No. the other method which is being called from synchronized code block will not be thread safe. It can be called by any other thread from any other code block if it does not have synchronized keyword, because the thread need not to acquire any lock to execute that method.
This is common misunderstanding that synchronized keyword locks piece of code.
What synchronized keyword does?
It locks the object and not the method. So if you put synchronized keyword in front of a method then it will lock this object. so any other method with synchronized keyword can not be executed by any other thread.
This is not the same with static and not static method because when you have synchronized static method then the it will not lock this but it will lock default class object i.e A.class object. If you have another static sync method then that will not be executed by any other thread.
In case of sync blocks it will acquire lock on the object which is passed as argument in your case it is args.
so if there is another sync block anywhere else which acquires lock on the same object then it will have to wait until the first thread completes and releases the lock.
There is always a lock present on synchronised code. To access the code threads have to acquire the key , unlock , run and then handback the key.
There is a object level lock present , the lock is of the entire object and not of some method or block. So even if there are multiple synchronized block or methods on a single instance only one of the threads can acquire the key and access the synchronized code. It will then hand back the key to the object and then other threads can resume to acquire key and access synchronized code.
Incase you are wondering what happens to the static methods declared syncrhonized (since they have no objects/instances associated with them), in that case there is always also a lock present with the class itself. To access any synchronized static part of a class, a thread has to acquire the key from the class to unlock the lock.
Note:- the lock and key thing I mentioned is just to help understand, there is no methods or way to access keys or anything it is all internally maintained by JVM.
First and foremost, there can be multiple synchronized methods in a class. That is done by:
declaring the methods as synchronized
synchronized methods .
As per your question, if the threads are of the same class(multiple threads requesting the same resource, then no two objects of the same class can access a particular resource at the same time(concurrently). The thread that is holding the mutually exclusive lock(mutex) is in the monitor. All other such threads has to undergo waiting for the monitor.
Java Thread Scheduler ensures that any of the synchronized method might be required by the thread which is currently in the monitor, i.e. the one which is holding the lock. So, does not allow other threads to execute them concurrently.
That is not the case with non-synchronized methods, they can execute concurrently.

How many threads may have access to the synchronized code of this Java object at any one time?

Assume the following class:
public class MyClass {
public synchronized void methodA() {
//...code
}
public synchronized void methodB() {
//...code
}
public synchronized void methodC() {
//...code
}
}
Assume that none of the synchronized methods of MyClass call each other.
Do I assume correctly that 1, and only 1 Thread may have access to ANY of the code of MyClass at any given time? If, for example, a thread is executing methodA() on an instance of MyClass, I assume that no other Thread may call either methodB() or methodC() at this time, but will block until the execution of methodA() by the first thread is complete.
I want to clarify my understanding of Goetz, Java Concurrency in Practice (28), who states:
"Acquiring the lock associated with an object does not prevent other threads from accessing that object--the only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock."
In this particular case, I argue, Goetz' first statement is incorrect. MyClass employs implicit locking on each of its 3 methods--for each method the implicit lock is itself (this). Therefore, in this case, if a thread holds the implicit lock while executing methodA(), all other threads will be prevented from accessing any of the code on this object.
Do I understand method synchronization and implicit locking correctly?
Any perspectives are greatly appreciated!
"Acquiring the lock associated with an object does not prevent other
threads from accessing that object--the only thing that acquiring a
lock prevents any other thread from doing is acquiring that same
lock."
Your three methods are declared as being synchronized. When one of those methods is invoked, like
MyClass instance = new MyClass();
instance.methodA();
the currently executing thread (call it A) will acquire that instance's monitor. No other thread will be able to acquire the same object's monitor until A has released it. Nothing prevents other threads from calling methods on that same object.
Say you had thread A doing
instance.methodA();
and thread B doing
instance.methodB();
Then, yes, thread B would have to wait for methodA to complete (ie. for thread A to release the lock on the object referenced by instance).
However, if thread A was doing
instance.methodA();
and thread B was doing
instance.toString();
thread B would not have to wait at all since toString() does nothing with the object's monitor.

A question on Java multi-threading

Assume the following class
public class TestObject{
public void synchronized method1(){
//some 1000 lines of code
}
public void method2(){
//some 1000 lines of code
}
}
Let's assume there are two threads accessing the same instance of TestObject class, let's call them t1 and t2. I want to know what will happen in the following scenario.
When t1 is in midway of accessing method1(). Now t2 is trying to access method2().
When t1 is in midway of accessing method2(). Now t2 is trying to access method1().
My understanding is that for the first question, the thread t2 will not be given permission as the object will be locked by t1. For the second question, the thread t2 will be granted access and takes lock on the object and will stall t1 from execution. But my assumption was wrong. Can anyone explain this?
Thanks
Only the method with the keyword synchronized holds a lock for this object when a thread is running in that method.
Had both method 1 and method 2 been declared as synchronized, one thread would block the other even though they are trying to run different methods.
In your example only 1 method is blocking by an implicit lock.
As a result t1 and t2 can be running concurrently in method 1 and method 2 (or vice versa).
Only when trying to access method 1, a t1 or t2 would block if the lock has already been acquired
When you declare a method to be synchronized, e.g.:
public synchronized void foo() {
// Do something
}
the compiler treats it as though you had written this:
public void foo() {
synchronized (this) {
// Do something
}
}
In your example you have one synchronized method and one non-synchronized. This means that only access to method1 will be locked. Locking checks are only done on entry to a synchronized block, so calling method2 will not trigger any locking.
To answer your two questions, then, in both cases the two threads will be allowed to proceed because they are not trying to obtain a lock on the same object. If you declare method2 to be synchronized (or manually add a synchronized (this) block) then one thread will be forced to wait for the other.
Remember: synchronizing on an object does not prevent other threads calling methods on that object. It only prevents another thread entering a synchronized block with the same lock object.
Incidentally, it's often better to have an internal lock object rather than declaring methods to be synchronized, e.g.
class Foo {
private final Object LOCK = new Object();
public void doSomething() {
synchronized (LOCK) {
// Whatever
}
}
}
Otherwise I can break your thread-safety by doing this:
class MessEverythingUp {
public MessEverythingUp(Foo foo) {
synchronized (foo) {
while (true) {
System.out.println("Pwnd ur thread safety");
}
}
}
}
Since I'm locking the instance of foo, your synchronized methods (with their implicit "synchronized (this)") will not be able to obtain a lock and will block forever. Most importantly, you cannot prevent this because I can synchronize on whatever object I like. Obviously the example is extreme but you can get nasty, subtle deadlock bugs if you're not careful about this sort of thing.
In both cases, the second thread will be given permission to execute its method.
Since only one of these two methods contains the synchronized keyword, both of these methods can be executed simultaneously. The restriction is that only one method with that keyword can be executed at any given time, because executing that method requires a lock on the object. A thread without the keyword requires no lock and will always be allowed to execute regardless of the object being locked.
I also assume here that the 1000 lines of code in method2 does not contain a block like this:
synchronized (this) {
}
If it does, then the results will be different.
t2 will be allowed to start executing the method. When it hits the synchronized line, it will wait for t1 to finish method1 and release its lock before continuing.
t2 will be allowed to start executing the method so long as t1 is not within the synchronized code block. If it is, t2 will wait until t1 exits the block and releases the lock before beginning. If t1 has not yet entered the synchronized block, then t2 will acquire the lock, and t1 will wait as soon as it gets to the synchronized code block until t2 completes the method and releases the lock.
One method is synchronized while the other is not. So no matter whether the lock on an Object (in this is case the instance the method belongs to) has been acquired or not, the non-synchronized method will execute unimpeded (since it foes not try to acquire or wait for a lock). Which means in both cases both threads will run without waiting for each other - resulting in a possibly inconsistent state of the object.
method1() is synchronized and hence called as thread safe method. When multiple threads try to access this method simultaneously then only the lock on instance object will work.
method2() is not synchronized and hence is a thread unsafe method, other threads can call this method even if the some other thread has lock on the instance, that is why this method is called as thread unsafe method.
In both cases you mentioned one thread will get lock on the instance by calling method1() and other thread will try to access method2() which is unsafe and hence both thread will execute.
with regards
Tushar Joshi, Nagpur
Both threads will execute as if the lock does not exist.
The thread accessing method2 will never know that it should get a lock so it will execute even if an other thread holds the lock. Only synchronized methods will reserve the lock since synchronization is optional and not always wanted or even necessary.
If both threads execute method1 one of them will block until the other thread exits the method and releases the lock.
To make sure only one thread executes and all others wait you have to make both methods synchronized.

Categories