In our earlier post, we learnt that when a method is synchronized, only one thread will be allowed to enter the method. In this post, let’s do a little bit of deep dive – let’s discuss whether threads can invoke the same synchronized method on different objects at the same point in time.
Video: To see the visual walk-through of this post, click below:
Multiple synchronized methods in a same object example
To facilitate our study, I have put-together an interesting program. In this program, we are trying to simulate two threads trying to execute the same synchronized method of different objects at the same point in time.
01: public class GirlFriend {
02:
03: private String girlFriendName;
04:
05: public GirlFriend(String name) {
06:
07: this.girlFriendName = name;
08: }
09:
10: public synchronized void meet() {
11:
12: String boyFriendName = Thread.currentThread().getName();
13: System.out.println(boyFriendName + " - " + girlFriendName + " meeting started");
14: try {Thread.sleep(100);} catch (Exception e) {}
15: System.out.println(boyFriendName + " - " + girlFriendName + " meeting completed");
16: }
17: }
This program has a ‘GirlFriend’ class. It contains a synchronized method ‘meet()’. This method prints the ‘Boyfriend’ thread name and ‘GirlFriend’ object name with text ” meeting started!” and ” meeting completed”
We have put the thread to sleep for 100 milliseconds in line #14 to simulate as if the meeting is held for 100 milliseconds. It also facilitates us to capture thread dumps during the program execution, which is needed for our discussion.
01: public class DiffObjectSynchDemo {
02:
03: private static class BoyFriend extends Thread {
04:
05: private GirlFriend girlFriend;
06:
07: public BoyFriend(GirlFriend girlFriend) {
08:
09: this.girlFriend = girlFriend;
10: }
11:
12: @Override
13: public void run() {
14:
15: girlFriend.meet();
16: }
17: }
18:
19: public static void main(String args[]) {
20:
21: GirlFriend girlFriend1 = new GirlFriend("GirlFriend1");
22: BoyFriend boyFriend1 = new BoyFriend(girlFriend1);
23: boyFriend1.setName("BoyFriend1");
24: boyFriend1.start();
25:
26: GirlFriend girlFriend2 = new GirlFriend("GirlFriend2");
27: BoyFriend boyFriend2 = new BoyFriend(girlFriend2);
28: boyFriend2.setName("BoyFriend2");
29: boyFriend2.start();
30: }
31: }
In this DiffObjectSynchDemo program, we are doing the following:
a. Creating ‘girlFriend1’ object and assigning to ‘boyFriend1’ thread and launching this thread from line #21 – #24.
b. Creating ‘girlFriend2’ object and assigning to ‘boyFriend2’ thread and launching this thread from line #26 – #29.
c. We are invoking ‘meet()’ method on the ‘GirlFriend’ object from both threads in line #15.
Basically, we are trying to have two threads execute the same synchronized method ‘meet()’ on two different objects.
Synchronized methods execution output
When we executed the above program, we got following as output:
01: BoyFriend1 - GirlFriend1 meeting started!
02: BoyFriend2 - GirlFriend2 meeting started!
03: BoyFriend1 - GirlFriend1 meeting completed!!
04: BoyFriend2 - GirlFriend2 meeting completed!!
Fig: Program Output
You can see that ‘BoyFriend1 – GirlFriend1 meeting started!’ printed as the first statement. However, even before their meeting gets completed, we could see the ‘BoyFriend2 – GirlFriend2 meeting started!’ (line #2) statement to be printed. Isn’t this behavior being in contrast to synchronized method description? Shouldn’t the BoyFriend1 – GirlFriend1 meeting complete first, before the ‘BoyFriend2 – GirlFriend2 meeting starts? No. Please read further to know why.
How does the same Synchronized method on different objects work in Java?
Each object has its own unique lock. When a thread executes a synchronized method, it acquires the lock of that object alone. When the ‘BoyFriend1’ thread executes the synchronized method ‘meet()’, it acquires the lock of the ‘GirlFriend1’ object. Similarly, when the ‘BoyFriend2’ thread executes the same synchronized method ‘meet()’, it acquires the lock of the ‘GirlFirend2’ object. Henceforth, there wouldn’t be any contention and both threads can execute the same synchronized ‘meet()’ method concurrently.
Threads behavior when executing same Synchronized on different objects
To confirm this theory, we executed the above program and captured thread dump using open-source script ‘yCrash’. We analyzed the thread dump using the fastThread tool. Here is the generated thread dump analysis report of this simple program. Below is the excerpt from the thread dump analysis report:
Fig: fastThread tool reporting no BLOCKED state threads
Unlike the previous example, where BLOCKED threads count were printed, in this thread dump analysis report, no BLOCKED threads are reported. This confirms that the ‘BoyFriend1’ and ‘BoyFriend2’ threads are running concurrently without blocking each other.
Conclusion
In this post, we learnt how JVM would behave when different threads try to execute the same synchronized methods on different objects. If you want to learn more details about the ‘synchronized’ method, you may refer here.
Leave a Reply