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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

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

  • Debugging With Confidence in the Age of Observability-First Systems
  • Driving DevOps With Smart, Scalable Testing
  • Creating a Web Project: Caching for Performance Optimization
  • Agentic AI and Generative AI: Revolutionizing Decision Making and Automation
  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
3.8K 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, DZone MVB. 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
Oops! Something Went Wrong

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!