If a synchronized method calls another synchronized method, is it thread safe?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
Yes, when you mark methods as synchronized, then you are really doing this:
void method1() {
synchronized (this) {
method2()
}
}
void method2() {
synchronized (this) {
}
}
When the thread call gets into method2 from method1, then it will ensure that it holds the lock to this, which it already has, and thus it can pass through.
Now when another thread tries to get directly into method1 or method2, then it will block until it can get the lock (this), and only then it will enter into any of the two methods.
As noted by James Black in the comments, you do have to be aware with what you do inside of the method body.
private final List<T> data = new ArrayList<T>();
public synchronized void method1() {
for (T item : data) {
// ..
}
}
public void method3() {
data.clear();
}
Suddenly it's not thread safe because you are looking at a ConcurrentModificationException in your future because method3 is unsynchronized, and thus could be called by Thread A while Thread B is working in method1.
Is a method marked with synchronized call another synchronized method thread safe.
In general, it is not possible to say. It depends on what the methods do, and what other methods on the same and other classes do.
However, we can be sure that calls to method1 and method2 on the same object made by different threads will not execute simultaneously. Depending on what the methods do, this may be sufficient to say that the class is thread-safe with respect to these methods.
From the Java Tutorials site http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
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.
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
So Java will ensure that if 2 threads are executing the same method, the methods will not executed consurrently but one after another.
But you need to be aware of the Liveness problem, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
And also whether you are locking uncessarily, cause in the code you used this, which locks the whole object, if your object only needs sync access to one variable you should just lock that variable.
Related
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){
...
}
}
My understanding is when an object method is 'synchronized', then only one thread is allowed in that method at once. I tested that and it worked.
But I was told recently that the "lock" that the thread must gain control of to access the synchronized method is an "object lock". Meaning that all of the methods of the object (synchronized or not) effectively behave in a synchronized manner.
I tested that, with synchronized void method1(); and void method2(); and it appears that many threads are able to enter method2 at the same time.
What is this "object lock" the guy was referring to and how does it work?
He meant that if you have two synchronized methods, they will be synchronized amongst each other and not just individually. This is because an object lock is held on the instance the method is called on.
In other words, if you have two synchronized methods foo() and bar(), no thread can call bar() while another thread is calling foo().
This is easy to see if you write out the definition. The synchronized method
public synchronized void foo() {
stuff;
}
is equivalent to:
public void foo() {
synchronized(this) {
stuff;
}
}
For methods with no associated instance (i.e., static methods), a lock is held on the Class instance instead.
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'.
I'm new to Java Threads and synchronization.
Lets say I have:
public class MyClass(){
public synchronized void method1(){
//call method2();
}
public synchronized void method2(){};
}
What does it mean when I synchronize a method1() on an instance object? So when a thread acquired the lock when trying to access the synchronized method1(), does it prevent other threads to access another synchronized method2() from that same object?
Lets say a thread acquires a lock when accessing method1(), but lets say that method1() makes a call to method2() which is also synchronized. Can this be possible? I mean are there any rules that can prevent method1() from calling method2()?
Thanks in advance.
Yes, using the synchronized method modifier on a non-static method means that it uses the monitor of the instance the method is invoked on, and this is shared between all such methods.
No - the thread already owns the monitor, so it is free to enter other blocks protected by the same monitor.
See here:
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.
Since this thread holds the lock on the current object, it can invoke method2(), and no other thread can.
A note on question 2, method1() can also call synchronized methods also in other classes which could cause a deadlock:
Thread1 calls synchronized method1() which in turn needs to call synchronized method_b() in AnotherClass
Thread2 holds the lock on AnotherClass and is executing a method that needs to call method1() in the class whose lock is held by Thread1
Both Threads will block waiting for the other to free the lock, a deadlock.
(1) This is equivalent to:
public void method1(){
synchronized (this) {
...
}
}
So it synchronizes on the current instance. If we rewrite method2 in the same way...
public void method2(){
synchronized (this) {
...
}
}
... then you can clearly see that they lock on the same object and thus other threads could not call method1 or method2 until method1 exits its synchronized block.
(2) synchronized blocks are re-entrant, meaning that the same thread can enter other synchronized blocks that lock on the same object as many times as it wants. As I understand it, every time you enter a synchronized block, Java increases a counter on the object you are synchronizing on by 1, and every time you exit a synchronized block, it decreases it. When that counter reaches 0, the lock is released.
This question already has answers here:
Is there an advantage to use a Synchronized Method instead of a Synchronized Block?
(23 answers)
Closed 5 years ago.
What is the difference between a synchronized method and synchronized block in Java ?
I have been searching the answer on the Net, people seem to be so unsure about this one :-(
My take would be there is no difference between the two, except that the synch block might be more localized in scope and hence the lock will be of lesser time ??
And in case of Lock on a static method, on what is the Lock taken ? What is the meaning of a Lock on Class ?
A synchronized method uses the method receiver as a lock (i.e. this for non static methods, and the enclosing class for static methods). Synchronized blocks uses the expression as a lock.
So the following two methods are equivalent from locking prospective:
synchronized void mymethod() { ... }
void mymethod() {
synchronized (this) { ... }
}
For static methods, the class will be locked:
class MyClass {
synchronized static mystatic() { ... }
static mystaticeq() {
syncrhonized (MyClass.class) { ... }
}
}
For synchronized blocks, you can use any non-null object as a lock:
synchronized (mymap) {
mymap.put(..., ...);
}
Lock scope
For synchronized methods, the lock will be held throughout the method scope, while in the synchronized block, the lock is held only during that block scope (otherwise known as critical section). In practice, the JVM is permitted to optimize by removing some operations out of the synchronized block execution if it can prove that it can be done safely.
A synchronized method is shorthand. This:
class Something {
public synchronized void doSomething() {
...
}
public static synchronized void doSomethingStatic() {
...
}
}
is, for all intents and purposes, equivalent to this:
class Something {
public void doSomething() {
synchronized(this) {
...
}
}
public static void doSomethingStatic() {
synchronized(Something.class) {
...
}
}
}
(Where Something.class is the class object for the class Something.)
So indeed, with a synchronized block, you can be more specific about your lock, and more fine-grained about when you want to use it, but other than that there's no difference.
Yes, that is one difference. The other is that you can acquire a lock on other objects than this.
The key difference is this: if you declare a method to be synchronized, then the entire body of the method becomes synchronized; if you use the synchronized block, however, then you can surround just the "critical section" of the method in the synchronized block, while leaving the rest of the method out of the block.
If the entire method is part of the critical section, then there effectively is no difference. If that is not the case, then you should use a synchronized block around just the critical section. The more statements you have in a synchronized block, the less overall parallelism you get, so you want to keep those to the minimum.
A synchronized method locks on the object instance the method is contained in.
Where as a synchronized block can lock on ANY object - typically a mutex obect defined as an instance variable. This allows more control over what locks are in operation.
My take would be there is no difference between the two, except that the synch block might be more localized in scope and hence the lock will be of lesser time ??
Yes. You are right. Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock.
Example from java tutorial:
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
Synchronized statements are also useful for improving concurrency with fine-grained synchronization. You can find good example on same tutorial page for below use case.
Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together. All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking. Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks.
And in case of Lock on a static method, on what is the Lock taken ? What is the meaning of a Lock on Class ?
In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.
When you make a method as synchronized ( non static ) :
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.
If you make a method as static synchronized :
It is not possible for two invocations of static synchronized methods on different objects of same class to interleave. When one thread is executing a static synchronized method for an object of Class A, all other threads that invoke static synchronized methods on any of objects of Class A block (suspend execution) until the first thread is done with the method execution.
You find better alternatives to synchronization in this SE question:
Avoid synchronized(this) in Java?