DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Writing DTOs With Java8, Lombok, and Java14+
  • Redefining Java Object Equality
  • Addressing Memory Issues and Optimizing Code for Efficiency: Glide Case
  • Singleton: 6 Ways To Write and Use in Java Programming

Trending

  • How to Format Articles for DZone
  • A Deep Dive into Tracing Agentic Workflows (Part 1)
  • How SaaS Architectures Break at Scale — and the Engineering Decisions That Prevent It
  • A Walk-Through of the DZone Article Editor
  1. DZone
  2. Coding
  3. Java
  4. Java Synchronized Block

Java Synchronized Block

In my earlier post, we learned about the Java synchronized method. In this post, let’s learn about the synchronized block.

By 
Ram Lakshmanan user avatar
Ram Lakshmanan
DZone Core CORE ·
Apr. 24, 23 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
4.0K Views

Join the DZone community and get the full member experience.

Join For Free

In my earlier post, we learned about the Java synchronized method. In this post, let’s learn about the synchronized block.

Video: To see the visual walk-through of this post, click below:


What Is Synchronized Block?

The synchronized block is used to prevent multiple threads from executing a portion of a code in a method at the same point in time. On the other hand, the synchronized method will prevent multiple threads from executing the entire method at the same point in time.

Synchronized Block Example

In our earlier post, we explained the synchronized method through the BoyFriend threads and the GirlFriend example program. Now, let’s rewrite the same example program using the synchronized block approach.

Java
 
01: public class SynchronizationBlockDemo { 
02:        
03:    private static class BoyFriendThread extends Thread { 
04:        
05:       @Override 
06:       public void run() { 
07:           
08:          girlFriend.meet(); 
09:       } 
10:    } 
11:  
12:    private static GirlFriend girlFriend = new GirlFriend(); 
13:     
14:    public static void main(String[] args) { 
15:        
16:       for (int counter = 0; counter < 10; ++counter) { 
17:           
18:          BoyFriendThread fThread = new BoyFriendThread(); 
19:          fThread.setName("BoyFriend-" + counter); 
20:          fThread.start(); 
21:       } 
22:    } 
23: }


Note: we haven’t made any changes to how we are launching the BoyFriend threads. It remains as is. However, we have modified the GirlFriend class to use the synchronized block as shown below:

Java
 
01: public class GirlFriend { 
02:     
03:    private Object assistant = new Object();    
04:     
05:    public void meet() { 
06:        
07:       synchronized (assistant) { 
08:        
09:          try { 
10:              
11:             String threadName = Thread.currentThread().getName(); 
12:             System.out.println(threadName + " meeting started!"); 
13:             Thread.sleep(100); 
14:             System.out.println(threadName + " meeting ended!!");          
15:          } catch (Exception e) {             
16:          } 
17:       }          
18:    }    
19: }


If you notice, in the GirlFriend class, we have introduced a new object, the assistant in line #3. Instead of making the entire meet() method as synchronized, we have now introduced synchronized (assistant) { in line #7. This synchronized block ends on line #17, and it will prevent multiple threads from executing these lines of code. Only one thread will be allowed to execute the code from line #8 to #17 at any given time. When we executed the above program, below is the output we got: 

Java
 
BoyFriend-0 meeting started! 
BoyFriend-0 meeting ended!! 
BoyFriend-9 meeting started! 
BoyFriend-9 meeting ended!! 
BoyFriend-8 meeting started! 
BoyFriend-8 meeting ended!! 
BoyFriend-7 meeting started! 
BoyFriend-7 meeting ended!! 
BoyFriend-6 meeting started! 
BoyFriend-6 meeting ended!! 
BoyFriend-5 meeting started! 
BoyFriend-5 meeting ended!! 
BoyFriend-4 meeting started! 
BoyFriend-4 meeting ended!! 
BoyFriend-3 meeting started! 
BoyFriend-3 meeting ended!! 
BoyFriend-2 meeting started! 
BoyFriend-2 meeting ended!! 
BoyFriend-1 meeting started! 
BoyFriend-1 meeting ended!!


How Do Synchronized Blocks Work in Java?

JVM will allow only one thread to enter into a synchronized block code at a given point in time. When a thread enters a synchronized block, it acquires the lock of the object on which it’s synchronized. In the above example, it’s the assistant object. Only after this thread releases the lock will other threads be allowed to enter the synchronized block of the code. Say the BoyFriend-0 thread is executing the synchronized block of the code. Only after this thread exits the block will other threads be allowed to enter the synchronized block of code. Until then, all other threads which are trying to invoke the synchronized block of code will be put into the BLOCKED thread state.

Threads Behavior of a Synchronized Block

To confirm this theory, we executed the above program and captured the thread dump using the 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 1: fastThread tool reporting 9 threads are in BLOCKED state

                               Fig 1: fastThread tool reporting 9 threads are in BLOCKED state

Fig 2: fastThread tool reporting 9 threads to be in BLOCKED state when accessing assistant Object

Fig 2: fastThread tool reporting 9 threads to be in BLOCKED state when accessing assistant Object

fastThread tool reports the total number of blocked threads and a transitive graph showing where they are BLOCKED. In this example (Fig 1), the tool reported that 9 threads are in BLOCKED state. From the transitive graph (Fig 2), you can notice that the BoyFriend1 is blocking the remaining 9 BoyFriend threads. When clicking on the thread names, you can see its complete stack trace. Below is the stack trace of one of the BoyFriend threads which is BLOCKED:

Java
 
01: java.lang.Thread.State: BLOCKED (on object monitor) 
02: at learn.synchblock.GirlFriend.meet(GirlFriend.java:13) 
03: - waiting to lock <0x00000007141e4330> (a java.lang.Object) 
04: at learn.synchblock.SynchronizationBlockDemo$BoyFriendThread.run(SynchronizationBlockDemo.java:10) 
05: Locked ownable synchronizers: 
06: - None


The above stack trace is very similar to the BLOCKED BoyFriend thread stack trace in the synchronized method example. However, there is only one difference. In line #3, this BoyFriend thread is waiting to acquire the lock of the java.lang.Object (i.e. assistant), whereas in the synchronized method example, the BoyFriend thread was waiting to acquire the lock of the GirlFriend object. Below is the stack trace of the BLOCKED BoyFriend thread in the synchronized method example:

Java
 
01: java.lang.Thread.State: BLOCKED (on object monitor) 
02: at learn.synchornized.GirlFriend.meet(GirlFriend.java:7) 
03: - waiting to lock <0x0000000714173850> (a learn.synchornized.GirlFriend) 
04: at learn.synchornized.SynchronizationDemo$BoyFriendThread.run(SynchronizationDemo.java:10) 
05: Locked ownable synchronizers: 
06: - None


Advantages of Synchronized Block Over Synchronized Method

Synchronized block has the following advantages when compared to the synchronized method:

A. Synchronize Only Portion of Method

 When you use a synchronized method, the entire code in that method will be synchronized. Say, suppose you want to synchronize only a portion of code in the method. You can’t use the synchronized method. In that circumstance, you need to use a synchronized block.

B. Synchronize on Any Object

 When you use a synchronized method, you can’t use any other object other than the underlying object (in the case of a static synchronized method, it would be the underlying class) of that method for synchronization. On the other hand, when you use a synchronized block, you can use any object. In the above example, we are using an ‘assistant’ object for synchronization (Which is totally different from the GirlFriend object in which this method was present).

C. Change Synchronizing Objects Based on Certain Conditions

 You can change the objects on which you are synchronizing dynamically. Look at the below example:

Java
 
01: public void doSomething(Object myLock) { 
02: 
03:    : 
04:    : 
05:   synchronize (myLock) { 
06:    
07:     // code to be synchronized 
08:   } 
09:   : 
10:   : 
11: }


Here, we are synchronizing the myLock object. However, the myLock can have different objects based on the invoker of the doSomething() method. Maybe, for each customer, we can pass different myLock objects. This is not achievable with synchronized methods.

Disadvantages of Synchronized Block Over Synchronized Method

Synchronized block has the following disadvantages when compared to the synchronized method:

Clean Code

Code readability is better with the synchronized method over the synchronized block. In the synchronized method scenario, it’s enough if you can just insert the synchronized keyword in the method declaration, whereas in the synchronized block, you need to do several additional things. Below is the code of a synchronized method and synchronized block:

synchronized method

                                                                                Fig: Synchronized Block

 You can notice that in the synchronized block, you need to do the following additional steps:

  1. Declare the synchronizing object
  2. Write one extra line of code on the synchronizing object
  3. Code to be synchronized needs to be given one more extra level of tab 
  4. Need to put one extra opening brace and closing brace

 It clutters your code when compared to synchronized methods.

Safe Code

Synchronized methods might be safer to write than synchronized blocks for the following two reasons:

a) NullPointerException

In a synchronized block, you synchronize the code block on a new object. At runtime, the synchronizing object can turn out to be null. In those circumstances, you will end up getting a NullPointerException.

b) Synchronizing on unsafe objects

There are certain objects which are risky to synchronize. Example: Strings and Boxed Objects (Integer, Float, Double,…). Because these objects are deduplicated by the JVM at runtime for optimal performance. In such circumstances, synchronized blocks will not work properly, and it will lead to nasty bugs in your application.

Blocks Java (programming language) Object (computer science)

Published at DZone with permission of Ram Lakshmanan. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Writing DTOs With Java8, Lombok, and Java14+
  • Redefining Java Object Equality
  • Addressing Memory Issues and Optimizing Code for Efficiency: Glide Case
  • Singleton: 6 Ways To Write and Use in Java Programming

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook