Friday, April 19, 2024
HomeJavaJava Static Synchronized technique habits - Java Code Geeks

Java Static Synchronized technique habits – Java Code Geeks


In our earlier put up, we learnt that when a way is synchronized, just one thread will probably be allowed to enter the strategy. On this put up, let’s focus on the habits of static synchronized strategies.


Video: To see the visible walk-through of this put up, click on beneath:


A number of static synchronized strategies in a similar object instance

To facilitate our research, I’ve put-together an attention-grabbing program. On this program, we are attempting to simulate two threads attempting to execute two static synchronized strategies on the similar cut-off date.

01: public class GirlFriend {

02: 

03:    public static synchronized void sing() {

04:       

05:       strive {         

06:           for(int i = 1; i <= 10; ++i) {

07:                System.out.println("lullaby");

08:                Thread.sleep(100);

09:          }

10:       } catch (Exception e) {         

11:       }

12:    }

13:    

14:    public static synchronized void depend() {

15:       

16:       strive {

17:           for(int i = 1; i <= 10; ++i) {

18:                System.out.println(i);

19:                Thread.sleep(100);

20:          }

21:       } catch (Exception e) {         

22:       }

23:    }   

24: }

 This program has a ‘GirlFriend’ class. It comprises two static synchronized strategies: 

 1. ‘sing()’ static technique declared in line #3 which prints ‘lullaby’ 10 occasions.

 2. ‘depend()’ static technique declared in line #14 which prints ‘1’ to ’10’.

Now we have put the thread to sleep for 100 milliseconds after printing in line #8 and #19, in order that we will seize thread dumps throughout this system execution, which is required for our dialogue.

01: public class StaticSynchDemo {

02:    

03:    non-public static class BoyFriend1 extends Thread {

04:       

05:       @Override

06:       public void run() {

07:          

08:          GirlFriend.sing();

09:       }

10:    }

11:    

12:    non-public static class BoyFriend2 extends Thread {

13:          

14:       @Override

15:       public void run() {

16:          

17:          GirlFriend.depend();

18:       }

19:    }

20:    

21:    public static void primary(String args[]) {

22:       

23:       new BoyFriend1().begin();

24:       new BoyFriend2().begin();

25:    }

26: }

This StaticSynchDemo class comprises two threads:

a. ‘BoyFriend1’ thread which invokes ‘GirlFriend’ class’s static synchronized ‘sing()’ technique in line #8

b. ‘BoyFriend2’ thread which invokes ‘GirlFriend’ class’s static synchronized ‘depend()’ technique in line #17

Each of those threads are launched concurrently in line #23, #24.

Static Synchronized strategies execution output

After we executed the above program, we obtained following as output:

lullaby

lullaby

lullaby

lullaby

lullaby

lullaby

lullaby

lullaby

lullaby

lullaby

1

2

3

4

5

6

7

8

9

10

Fig: Output when sing() and depend() is static synchronized

You’ll be able to see that the ‘GirlFriend’ class first completes singing after which begins the counting although each the ‘BoyFriend1’ and ‘BoyFriend2’ threads attempt to invoke the ‘GirlFriend’ class at similar time. This magic is occurring solely due to synchronization. 

How do two static Synchronized strategies work in Java?

When a thread executes the static synchronized technique, it obtains the lock of the java.lang.Class of that specific object (i.e., GirlFriend’s class object). Just one thread can maintain the lock of the category object at any given time. Because the ‘BoyFriend1’ thread began first, when it entered the ‘sing()’ technique it acquired the ‘GirlFriend class’ object lock. At the moment, ‘BoyFriend2‘ thread tries to enter the ‘depend()’ technique and it’ll attempt to purchase the lock of the identical ‘GirlFriend class’ object. Because the ‘BoyFriend1’ thread is already holding on to the GirlFriend’s class lock, the ‘BoyFriend2’ thread is not going to be allowed to amass the lock and will probably be put to the BLOCKED state. Solely after the ‘BoyFriend1’ thread exits ‘sing()’ technique, it is going to launch the GirlFriend’s class lock, solely after that the ‘BoyFriend2’ thread will enter the ‘depend()’ technique.

Thread habits of static synchronized strategies

To substantiate this principle, we executed the above program and captured thread dump utilizing open-source script yCrash. We analyzed the thread dump utilizing the fastThread device. Right here is the generated thread dump evaluation report of this easy program. Beneath is the excerpt from the thread dump evaluation report:

Fig: fastThread device reporting 1 thread is in BLOCKED state
Fig: Transitive graph displaying ‘BoyFriend2’ blocked by ‘BoyFriend1’ (generated by fastThread)

Every time threads are blocked, fastThread device will report them as a transitive graph. From the graph, you possibly can discover that ‘BoyFriend2’ is being blocked by ‘BoyFriend1’. (Notice: This graph would make extra sense particularly when a number of threads are getting blocked. You’ll be able to have a look at the introductory put up the place a number of threads obtained BLOCKED). When clicking on the thread names you possibly can see its full stack hint. Beneath are each threads stack hint:

01: BoyFriend1 Stack Hint is:

02: java.lang.Thread.State: TIMED_WAITING (sleeping)

03: at java.lang.Thread.sleep0(java.base@19.0.1/Native Technique)

04: at java.lang.Thread.sleep(java.base@19.0.1/Thread.java:465)

05: at be taught.synchornized.stat.GirlFriend.sing(GirlFriend.java:10)

06: - locked <0x0000000713e71e00> (a java.lang.Class for be taught.synchornized.stat.GirlFriend)

07: at be taught.synchornized.stat.StaticSynchDemo$BoyFriend1.run(StaticSynchDemo.java:14)

08: Locked ownable synchronizers:

09: - None

Fig: BoyFriend1 thread stack hint displaying it acquired the GirlFriend class lock in line #6

01: BoyFriend2 Stack Hint is:

02: java.lang.Thread.State: BLOCKED (on object monitor)

03: at be taught.synchornized.stat.GirlFriend.depend(GirlFriend.java:19)

04: - ready to lock <0x0000000713e71e00> (a java.lang.Class for be taught.synchornized.stat.GirlFriend)

05: at be taught.synchornized.stat.StaticSynchDemo$BoyFriend2.run(StaticSynchDemo.java:23)

06: Locked ownable synchronizers:

- None

Fig: BoyFriend2 thread obtained BLOCKED when attempting to amass the GirlFriend class lock in line #4

You’ll be able to discover that the ‘BoyFriend2’ thread is blocked (line #4), as a result of it’s attempting to amass the lock ‘0x0000000713e71e00’ (which is the item id of ‘GirlFriend class’) when it’s attempting to invoke the ‘depend()’ technique. Then again, you possibly can discover that the ‘BoyFriend1’ thread acquired the identical lock ‘0x0000000713e71e00’ and executed the ‘sing()’ technique. ‘BoyFriend1’ thread wouldn’t launch this lock till it completes executing the ‘sing()’ technique. Thus, ‘BoyFriend2’ thread is stranded and put into the BLOCKED state.

Static Synchronized and non-static Synchronized technique

To make our research somewhat bit extra attention-grabbing, we’ll attempt to perceive the habits when a static synchronized technique and non-static synchronized technique is concurrently invoked on the similar cut-off date. To facilitate this research, I’ve modified the above program barely. 

01: public class GirlFriend {

02: 

03:    public static synchronized void sing() {

04:       

05:       strive {         

06:           for(int i = 1; i <= 10; ++i) {

07:                System.out.println("lullaby");

08:                Thread.sleep(100);

09:          }

10:       } catch (Exception e) {         

11:       }

12:    }

13:    

14:    public synchronized void depend() {

15:       

16:       strive {

17:           for(int i = 1; i <= 10; ++i) {

18:                System.out.println(i);

19:                Thread.sleep(100);

20:          }

21:       } catch (Exception e) {         

22:       }

23:    }   

24: }

This program has a ‘GirlFriend’ class. It comprises two strategies: 

 1. ‘sing()’ static synchronized technique declared in line #3 which prints ‘lullaby’ 10 occasions.

 2. ‘depend()’ synchronized technique declared in line #14 which prints ‘1’ to ’10’.

Now we have put the thread to sleep for 100 milliseconds after printing in line #8 and #19, in order that we will seize thread dumps throughout this system execution, which is required for our dialogue.

01: public class StaticNonStaticSynchDemo {

02:    

03:    non-public static class BoyFriend1 extends Thread {

04:       

05:       @Override

06:       public void run() {

07:          

08:          GirlFriend.sing();

09:       }

10:    }

11:    

12:    non-public static class BoyFriend2 extends Thread {

13:          

14:       non-public GirlFriend myGirlFriend = new GirlFriend();

15:       

16:       @Override

17:       public void run() {

18:          

19:          myGirlFriend.depend();

20:       }

21:    }

22:    

23:    public static void primary(String args[]) {

24:       

25:       new BoyFriend1().begin();

26:       new BoyFriend2().begin();

27:    }

28: }

This ‘StaticNonStaticSynchDemo’ class comprises two threads:

a. ‘BoyFriend1’ thread which invokes ‘GirlFriend’ class static synchronized ‘sing()’ technique in line #8

b. ‘BoyFriend2’ thread which invokes ‘GirlFriend’ object’s synchronized ‘depend()’ technique in line #19

Each of those threads are launched concurrently in line #25, #26.

Static Synchronized & non-static synchronized strategies execution output

 After we executed the above program, we obtained following as output:

lullaby

1

2

lullaby

lullaby

3

lullaby

4

lullaby

5

lullaby

6

7

lullaby

lullaby

8

lullaby

9

lullaby

10

Fig: Output when invoking static synchronized sing() technique and non-static synchronized depend() technique

From the output, you possibly can discover that the ‘GirlFriend’ is singing and counting concurrently. i.e., you possibly can see that the ‘lullaby’ and numbers are printed in a blended up method. Despite the fact that strategies are synchronized, why this type of blended up habits taking place? 

How does JVM execute static synchronized & non-static synchronized strategies?

When a thread executes the static synchronized technique, it obtains the lock of the java.lang.Class of that specific object (i.e., ‘GirlFriends class’ object). Then again, when a thread executes a non-static synchronized technique, it obtains the lock of that object itself (i.e, ‘GirlFriend’ object). Thus, within the above instance, ‘BoyFriend1’ thread acquires the lock of ‘GirlFriend class’ when it enters ‘sing()’ technique, whereas ‘BoyFriend2’ thread acquires the lock of the ‘GirlFriend’ object when it enters ‘depend()’ technique. These are two completely different locks. Thus, each the ‘BoyFriend1’ thread and ‘BoyFriend2’ thread can execute the ‘sing()’ and ‘depend()’ strategies concurrently. That’s the rationale why you’re seeing the ‘lullaby’ string the numbers to be blended up and printed.

Threads habits of static synchronized strategies

To substantiate this principle, we executed the above program and captured thread dump utilizing open-source script yCrash. We analyzed the thread dump utilizing the fastThread device. Right here is the generated thread dump evaluation report of this easy program. Beneath is the excerpt from the thread dump evaluation report:

Fig: fastThread device reporting no BLOCKED state threads

Fig: fastThread device reporting no BLOCKED state threadsWithin the earlier instance, you’ll have observed that the BLOCKED thread depend printed as 1, whereas on this thread dump evaluation report, there aren’t any BLOCKED threads reported. This confirms that the ‘BoyFriend1’ and ‘BoyFriend2’ threads are operating concurrently with out blocking one another. 

Conclusion

On this put up, we learnt intimately how static synchronized strategies would work. To be taught extra about Java concurrency it’s possible you’ll refer right here.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments