About calling methods from a synchronized block
Asked Answered
M

2

5

Is synchronizing a method equivalent to letting only one thread to evaluate it until it's out of scope including inner method calls?

For example:

public synchronized void foo(){

    if(critical condition){
        bar();  // can influence the above condition
    }
    baz(); // can influence the above condition
}

Can two threads be in bar (suppose it's called only from here)?

What if baz can be called from another place in the code other than foo, can two threads be in it then?

Mime answered 16/10, 2016 at 15:31 Comment(0)
A
3

This is an equivalent way of writing your code:

public void foo(){
    synchronized (this) {
        if(critical condition){
            bar();  // can influence the above condition
        }
        baz(); // can influence the above condition
    }
}

Because synchronized methods actually synchronize their bodies using this as the lock object.

So, can two threads be executing foo() at the same time or bar() at the same time? Sure, if they are executing the foo() or bar() of different objects.

Also, the call to baz() is not synchronized at all, so even any two threads can run the baz() of single object at the same time, as long as at least one of them is invoking it from outside foo().

These two resources are useful for understanding what synchronization does and doesn't do in Java:

I recommend you check those pages because there are some pieces of information that are not too obvious until you check them. For example:

  • Two different threads cannot execute at the same time two different synchronized methods of a single object.
  • A single thread can be executing two different synchronized methods of the same object (called Reentrant Synchronization)
Aleurone answered 16/10, 2016 at 17:2 Comment(5)
So it looks like if I'll sync bar() and baz(), one thread will take this as the lock and use it through both bar, baz till the end of foo and only one thread?Mime
I saw those links before I asked the question, they don't have an example of a method call from a sync block...Mime
The lock that a thread acquires when entering foo will remain with the thread until exiting foo, even if inside foo you are calling other methods. While the thread is inside bar it still is retaining the lock because foo is still in execution.Aleurone
Got it, and I could just sync baz so another thread won't go into it at the same time.Mime
Yeap, that's how it works. Synchronizing baz avoids another thread will enter to baz or foo for this same object if your original thread is in either baz or foo.Aleurone
K
5

Can two threads be in bar (suppose it's called only from here)?

Yes, provided they are using different objects, or one is wait()ing.

What if baz can be called from another place in the code other than foo, can two threads be in it then?

Yes, placing synchronized on one method has no effect on methods which are not synchronized.

Kant answered 16/10, 2016 at 15:35 Comment(6)
By different object you mean a different instance of the class foo is in? Also, would placing a lock on foo make only one thread to be in bar or baz?Mime
@kuhaku you can have multiple instances of the class which implements foo() if you have only one instance and only one method which can call bar() and baz() then only one thread can be in these methods (unless you use wait())Kant
More than one method can call baz() and there are several instances of the enclosing class but they act on themselves not on eachother...Mime
@kuhaku in which case any number of threads could be running that method. Imagine you have two cities, each with an impregnable gate, but no walls. Can two people get into a city at the same time?Kant
So if there are several instances of the same class, two threads can go to the same instance but if the class is a singleton, only one?Mime
@kuhaku Each object has one lock (Unless it's a Lock) if you have two instances, two threads can hold a lock on each one and be in the same method (but with a different instance) What is important is how the objects are locked or not. You don't lock methods. Locking an object has no effect on code which doesn't use synchronized.Kant
A
3

This is an equivalent way of writing your code:

public void foo(){
    synchronized (this) {
        if(critical condition){
            bar();  // can influence the above condition
        }
        baz(); // can influence the above condition
    }
}

Because synchronized methods actually synchronize their bodies using this as the lock object.

So, can two threads be executing foo() at the same time or bar() at the same time? Sure, if they are executing the foo() or bar() of different objects.

Also, the call to baz() is not synchronized at all, so even any two threads can run the baz() of single object at the same time, as long as at least one of them is invoking it from outside foo().

These two resources are useful for understanding what synchronization does and doesn't do in Java:

I recommend you check those pages because there are some pieces of information that are not too obvious until you check them. For example:

  • Two different threads cannot execute at the same time two different synchronized methods of a single object.
  • A single thread can be executing two different synchronized methods of the same object (called Reentrant Synchronization)
Aleurone answered 16/10, 2016 at 17:2 Comment(5)
So it looks like if I'll sync bar() and baz(), one thread will take this as the lock and use it through both bar, baz till the end of foo and only one thread?Mime
I saw those links before I asked the question, they don't have an example of a method call from a sync block...Mime
The lock that a thread acquires when entering foo will remain with the thread until exiting foo, even if inside foo you are calling other methods. While the thread is inside bar it still is retaining the lock because foo is still in execution.Aleurone
Got it, and I could just sync baz so another thread won't go into it at the same time.Mime
Yeap, that's how it works. Synchronizing baz avoids another thread will enter to baz or foo for this same object if your original thread is in either baz or foo.Aleurone

© 2022 - 2024 — McMap. All rights reserved.