Full Stack Web Development Internship Program
- 29k Enrolled Learners
- Weekend/Weekday
- Live Class
Multi-threaded programs may regularly come up with a circumstance where multiple Java threads attempt to get to the same resource which produces fraudulent and startling outcomes. This can be solved by using the synchronization in Java. Just a single specific thread can get to the resource at a given purpose of time. This article will help you to become familiar with the synchronization strategy.
I’ll be discussing the topics in this order:
Let’s get started!
Why use Synchronization in Java?
If you start with at least two threads inside a program, there might be a chance when multiple threads attempt to get to the same resource. It can even create an unexpected outcome because of concurrency issues.
Syntax:
synchronized(objectidentifier) { // Access shared variables and other shared resources; }
For example, multiple threads attempt to write within an equivalent file. This may corrupt the data since one of the threads can override the data or when a thread is opening the same file at the same time, another thread might be closing the same file. There is a need to synchronize the action of multiple threads. This can be implemented using a concept called Monitors.
Synchronized blocks in Java are marked with the Synchronized keyword. This block in Java is synchronized on some object. All blocks that are synchronized on the same object can only have one thread executing inside them at a time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
There are basically two types of synchronization available. They are:
Let’s not get into the details of these types and try to understand what are locks in Java.
As I mentioned earlier, Synchronization is built around an internal entity known as the lock or monitor. Each and every object has a lock associated with it. So a thread that needs consistent access to an object’s fields needs to acquire the object’s lock before accessing them, and then release the lock when the work is done.
From Java 5, the package java.util.concurrent.locks contains many lock implementations.
This is how a lock looks like:
public class Lock { private boolean isLocked = false; public synchronized void lock() throws InterruptedException { while(isLocked) { wait(); } isLocked = true; } public synchronized void unlock() { isLocked = false; notify(); } }
The lock() method locks the Lock instance so that all threads calling lock() are blocked until unlock() is executed.
Here is a simple example which prints the counter value in a sequence and every time we run it, it produces a different result based on CPU availability to a thread. Check this out!
class Multithread { public void printCount() { try { for(int i = 5; i<0; i--) { System.out.println("Counter --- " + i ); } } catch (Exception e) { System.out.println("Thread interrupted."); } } } class Thread extends Multithread { private Thread t; private String threadName; Multithread MT; Thread( String name, Multithread mt) { threadName = name; MT= mt; } public void run() { MT.printCount(); System.out.println("Thread " + threadName + " exiting."); } public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class TestThread { public static void main(String args[]) { Multithread MT = new Multithread(); Thread t = new Thread( "Thread - 1 ", MT); Thread t1 = new Thread( "Thread - 2 ", MT); t.start(); t1.start(); // wait for threads to end try { t.join(); t1.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } }
The above program’s results in this:
Multi-threading with Synchronization
This is the same example as above but it prints the counter value in the sequence. Every time we run it, it produces the same result.
class Multithread { public void printCount() { try { for(int i = 5; i > 0; i--) { System.out.println("Counter --- " + i ); } } catch (Exception e) { System.out.println("Thread interrupted."); } } } class Thread extends Multithread { private Thread t; private String threadName; Multithread MT; Thread( String name, Multithread mt) { threadName = name; MT= mt; } public void run() { synchronized(MT) { MT.printCount(); } System.out.println("Thread " + threadName + " exiting."); } public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class TestThread { public static void main(String args[]) { Multithread MT = new Multithread(); Thread T = new Thread( "Thread - 1 ", MT); Thread T1 = new Thread( "Thread - 2 ", MT); T.start(); T1.start(); // wait for threads to end try { T.join(); T1.join(); } catch ( Exception e) { System.out.println("Interrupted"); } } }
The output is depicted below:
Synchronized Keyword
Java synchronized keyword marks a block or a method a critical section. A critical section is where only one thread is executing at a time, and the thread holds the lock for the synchronized section. This synchronized keyword helps in writing concurrent parts of any application. It also protects shared resources within the block.
The synchronized keyword can be used with:
Syntax
The general syntax for writing a synchronized block is:
synchronized ( lockObject) { //synchronized statements }
When a thread wants to execute the synchronized statements inside the block, it must acquire the lock on the lockObject‘s monitor. Only one thread can acquire the monitor of a lock object at a time. So all other threads must wait till the currently executing thread acquires the lock and finish its execution.
This way, the synchronized keyword guarantees that only one thread will be executing the synchronized block statements at a time, and thus prevents multiple threads from corrupting the shared data that is present inside the block.
Note:
sleep()
method) then it does not release the lock. During this sleep time, no thread will be executing the synchronized block statements.Now, let’s discuss the method.
Syntax
The general syntax for writing a synchronized method is:
<access modifier> synchronized method ( parameters) { //synchronized code }
Here lockObject is just a reference to an object whose lock is associated with the monitor which represents the synchronized statements.
Similar to the synchronized block, a thread must acquire the lock on the connected monitor object with the synchronized method. In the case of synchronized method, the lock object is:
Java synchronized keyword is re-entrant in nature. It means if a synchronized method calls another synchronized method which requires the same lock, then current thread which is holding the lock can enter into that method without acquiring the lock.
Let us move ahead to the final topic of this article and point out the major differences between the synchronized keyword and synchronization block.
This brings us to the end of this article where we have discussed how exactly Synchronization in Java works. Hope you are clear with all that has been shared with you in this tutorial.
Check out the Java Certification Course by Edureka, a trusted online learning company with a network of more than 250,000 satisfied learners spread across the globe. We are here to help you with every step on your journey, for becoming a besides this java interview questions, we come up with a curriculum which is designed for students and professionals who want to be a Java Developer.
If you want to start a career in the Node JS Field then check out the Best Node JS Course by Edureka, a trusted online learning company with a network of more than 250,000 satisfied learners spread across the globe.
Got a question for us? Please mention it in the comments section of this “Synchronization in Java ”article and we will get back to you as soon as possible.
Course Name | Date | Details |
---|---|---|
Java Course Online | Class Starts on 28th September,2024 28th September SAT&SUN (Weekend Batch) | View Details |
edureka.co