synchronized(this) vs synchronized(MyClass.class) [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Synchronized Block for .class
I was reading through an article on synchronization. I am confused on below points and need more clarification
For synchronization block. How
synchronized (this) {
// code
}
differs from
synchronized (MyClass.class) {
// code
}
Synchronizing instance method means threads will have to get exclusive lock on the instance, while synchronizing static method means thread will have to acquire a lock on whole class(correct me if I am wrong). So if a class has three methods and one of them is static synchronized then if a thread acquires lock on that method then that means it will acquire lock on the whole class. So does that mean the other two will also get locked and no other method will be able to access those two methods as the whole class is having lock?

MyClass.class and this are different things, they are different references to different objects.
this - is a reference to this particular instance of the class, and
MyClass.class - is a reference to the MyClass description object.
These synchronization blocks differ in that the first will synchronize all threads that deal concretely with this instance of MyClass, and the second one will synchronize all threads independently of which object on which method was called.

The first example (acquiring lock on this) is meant to be used in instance methods, the second one (acquiring lock on class object) -- in static methods.
If one thread acquires lock on MyClass.class, other threads will have to wait to enter the synchronized block of a static method that this block is located in. Meanwhile, all of the threads will be able to acquire lock for a particular instance of this class and execute instance methods.

Related

Synchronizing multiple blocks within same method [duplicate]

This question already has answers here:
Java synchronize block on same object in different methods
(2 answers)
Closed 2 years ago.
Suppose I have synchronized two parts of code within a method. So block1 and block2 each have keyword 'synchronized' around them, and both use 'this', meaning both blocks are guarded by same object lock.
Now if block1 is being executed by a thread, does it mean no other thread can execute block2?
Synchronized on the method declaration is the same as:
public void method() {
synchronized (this) {
// method code
}
}
Having said that, as you can see in the oracle docs you can see an example with some synchronized methods and it says:
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.
So, yes, no other thread can execute block2 in that case.

Can a seperate thread continue execution on an object synchronised by another?

Say I have an object A which has 2 methods:
public doSomething()
{....}
public synchronised doSomethingElse()
{ ... }
and I have thread1.doSomethingElse(), will it still be possible for thread2.doSomething() to execute or is it blocked by thread1's lock?
If so, how can I make thread1 execute at the same time?
There are two types of synchronization
1. Object level
2. Class level (Class level synchronization is for the static methods only.)
In your case since your methods are not static it is object level synchronization. For object level synchronization you can either synchronize your whole methods or you can synchronize some block of your methods.
When you synchronized one method. Its mean that same object of your class cant access your synchronized method from different threads. As each object have only one lock. If you had called doSomethingElse() for same obj but from different threads. Then It will be accessible by one thread.
Now comes to your answer:
As your first method is not synchronized i.e something(). It will not be effected in any case if you call it for any no of threads or even call it when your first thread is currently in the method. Locks are only for synchronized methods
Yourclass obj = new Yourclass();
Thread A = new MyThread(obj);
Thread B = new MyThread(obj);
......
public void run()
{
\\do what ever you want
\\both of your methods will be called.
\\ call them both here.
}
here i have made objects of same Mythread class you can do as per you want. you can make objects of two different implemented thread classes and write your run. In any case it will have no effect on the call.
Since thread 2 is not attempting to acquire any lock, it is not blocked and can run concurrently with thread 1. There's nothing special you need to do.

What does "synchronize" exactly do? [duplicate]

This question already has answers here:
What does 'synchronized' mean?
(17 answers)
Closed 8 years ago.
I have a question which may sound very basic but here it is. As commonly known in Java the synchronize keyword is used to deal with multiples threads accessing one particular instance. Now imagine if an instance A has a synchronized method do(). Does that mean that if a thread T1 executes the method do() and therefore acquires the lock of A, no other thread will access the instance A until T1 releases the lock (even if other methods are not synchronized)? or it means that all not-synchronized methods (or blocks of code) are accessible except that particular do() method which maybe executed by only one thread at a time?
Straight from the Java documentation:
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.
Therefore, your latter explanation is correct.
If T1 gets a lock on method do() i.e method is under synchronized block.
and other portion of program say method display() is not synchronized then other threads can access this method.
So your or is correct.
A synchronized method ensures that this method is not called for more than one object instances simultaneously and also during execution of a synchronized method all the associated instance variables are refreshed before starting executing the method.

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.

if i call a non synchronized method from my synchronized method is non synchronized method thread safe?

I i make a call to noonsynchronized method from within my synchronized method is it thread safe?
I have 2 methods as follows:
public class MyClass{
void synchronized doSomething1(){
doSomething2();
}
void doSomething2(){
//will this block of code be synchronized if called only from doSomething1??
}
}
If doSomething2() is only called from doSomething1(), then it will only be called by a single thread for a single instance of MyClass. It could still be called from different threads at the same time, via different instances - so if it acts on any shared data which may not be specific to the instance of MyClass, it's still not guaranteed to fix all threading issues.
Basically, you need to think carefully about any mutable shared state used by multiple threads - there are no easy fixes to that, if you need mutable shared state. In your particular case you'd also need to make sure that doSomething2() was only called from doSomething1() - which would mean making it private to start with...
When calling doSomething1() the caller's Thread locks on the monitor of the instance of MyClass. Until that thread's execution exits doSomething1 the lock will remain which includes if it goes into doSomething2. This will cause other threads to block when attempting to lock.
Keep in mind:
synchronized does not thread-safe it make.
Further info:
JLS 3rd Ed 17.1 Locks
If doSomething2() is called ONLY from doSomething1() then yes - it is thread safe.

Categories