How multiple synchronized key words work in a single class? - java

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.

Related

Threading & locks in java

I heard that every object in java has an intrinsic lock associated with it. what if a thread take this lock to invoke synchronized method. does that mean no another thread can access any methods in this object or the synchronized methods only ?!
Just one thread can access synchronized methods at the same time.
See official documentation:
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.
synchronized on an instance method is shorthand for synchronized (this) { } around the entire method body. For static methods it is the equivalent of synchronized (this.class) { }. So just think synchronized (obj) { }.
Only a single thread can acquire a lock, so superficially only one thread can enter at a time. Loser threads block until the lock is available.
That's not the entire story. If somewhere within a synchronized block (perhaps in another method) the thread calls this.wait(); (with optional arguments), then that thread releases the lock for the duration of wait(). During this time the lock is available, for instance, to call this.notifyAll().
Also it worth noting that the lock is reentrant. Another, or the same, synchronized method can be called recursively.

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

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.

Does Thread lock on object ensures lock on member objects too?

Consider following class that I have wrote for testing the locking of non-primitive variable (myObject). If all threads are working on same object instance of SynchronizationTest, my questions are:
I understand that if thread1 is executing set(...) method then any other thread (lets say thread2) is okay to execute either of the anotherSetWithSynchronized(...) or anotherSetWithoutSynchronized(...).
If thread1 has locked the object of SynchronizationTest while executing set(...), does it mean it has acquired lock on all member object variable ? like in this case myObject. If not then,
If thread1 is executing set(...) can thread2 execute anotherSetWithSynchronized(...) concurrently?
Are none of the two methods can execute simultaneously by thread?
Is this design wrong? Do I need to explicitly lock myObject in synchronized set(...) method. Like this:
public synchronized void set(MyValue myValue) {
synchronized (myObject) {
myObject.put(myValue);
}
}
Here's my code:
public class SynchronizationTest {
private MyObject myObject = new MyObject();
public synchronized void set(MyValue myValue) {
myObject.put(myValue);
}
public void anotherSetWithSynchronized(MyValue myValue) {
synchronized (myObject) {
myObject.put(myValue);
}
}
public void anotherSetWithoutSynchronized(MyValue myValue) {
myObject.put(myValue);
}
}
1: No, set(...) method is guarded by "SynchronizationTest" Object's lock.
2: Yes, their guard objects are different as you've designed.
3: One thread can only run one method per time. If you mean two threads, as I've explained, the methods are guarded by two objects and therefore they can be executed simultaneously
4: Yes, you're right.
The intrinsic lock in Java is described as follows in the book "Java Concurrency In Practice":
A synchronized block has two parts: a reference to an object that
will serve as the lock, and a block of code to be guarded by that
lock. A synchronized method is shorthand for a synchronized block
that spans an entire method body, and whose lock is the object on
which the method is being invoked. (Static synchronized methods use
the Class object for the lock.)
For more details, you can refer to section 2.3.1 of "Java concurrency in Practice".
synchronized method is equivalent to
public void method(){
synchronized(this){
//something
}
}
1) no
Synchronization is only on specified objects, not on its members.
2) no
3) yes, they cannot, only one thread can be active inside synchronized section guarded by given monitor
4) you don't need to (and you should not use synchronized on method level if you are using explicit synchronization). BUT its better (for libraries/large codebase), because then you can controll who can acces instance on which synchronization occurs, so someone other can't synchronize on it and cause deadlock.
Does Thread lock on object ensures lock on member objects too?
No.
I understand that if thread1 is executing set(...) method then any other thread (lets say thread2) is okay to execute either of the anotherSetWithSynchronized
Yes, unless myObject has the same value as 'this'.

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.

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