Java Tutorial
- Java - Home
- Java - Overview
- Java - History
- Java - Features
- Java vs C++
- Java Virtual Machine (JVM)
- Java - JDK vs JRE vs JVM
- Java - Hello World Program
- Java - Environment Setup
- Java - Basic Syntax
- Java - Variable Types
- Java - Data Types
- Java - Type Casting
- Java - Unicode System
- Java - Basic Operators
- Java - Comments
Java Control Statements
- Java - Loop Control
- Java - Decision Making
- Java - If-else
- Java - Switch
- Java - For Loops
- Java - For-Each Loops
- Java - While Loops
- Java - do-while Loops
- Java - Break
- Java - Continue
Object Oriented Programming
- Java - OOPs Concepts
- Java - Object & Classes
- Java - Class Attributes
- Java - Class Methods
- Java - Methods
- Java - Variables Scope
- Java - Constructors
- Java - Access Modifiers
- Java - Inheritance
- Java - Aggregation
- Java - Polymorphism
- Java - Overriding
- Java - Method Overloading
- Java - Dynamic Binding
- Java - Static Binding
- Java - Instance Initializer Block
- Java - Abstraction
- Java - Encapsulation
- Java - Interfaces
- Java - Packages
- Java - Inner Classes
- Java - Static Class
- Java - Anonymous Class
- Java - Singleton Class
- Java - Wrapper Classes
- Java - Enums
- Java - Enum Constructor
- Java - Enum Strings
Java Built-in Classes
Java File Handling
- Java - Files
- Java - Create a File
- Java - Write to File
- Java - Read Files
- Java - Delete Files
- Java - Directories
- Java - I/O Streams
Java Error & Exceptions
- Java - Exceptions
- Java - try-catch Block
- Java - try-with-resources
- Java - Multi-catch Block
- Java - Nested try Block
- Java - Finally Block
- Java - throw Exception
- Java - Exception Propagation
- Java - Built-in Exceptions
- Java - Custom Exception
Java Multithreading
- Java - Multithreading
- Java - Thread Life Cycle
- Java - Creating a Thread
- Java - Starting a Thread
- Java - Joining Threads
- Java - Naming Thread
- Java - Thread Scheduler
- Java - Thread Pools
- Java - Main Thread
- Java - Thread Priority
- Java - Daemon Threads
- Java - Thread Group
- Java - Shutdown Hook
Java Synchronization
- Java - Synchronization
- Java - Block Synchronization
- Java - Static Synchronization
- Java - Inter-thread Communication
- Java - Thread Deadlock
- Java - Interrupting a Thread
- Java - Thread Control
- Java - Reentrant Monitor
Java Networking
- Java - Networking
- Java - Socket Programming
- Java - URL Processing
- Java - URL Class
- Java - URLConnection Class
- Java - HttpURLConnection Class
- Java - Socket Class
- Java - Generics
Java Collections
Java Interfaces
- Java - List Interface
- Java - Queue Interface
- Java - Map Interface
- Java - SortedMap Interface
- Java - Set Interface
- Java - SortedSet Interface
Java Data Structures
Java Collections Algorithms
Advanced Java
- Java - Command-Line Arguments
- Java - Lambda Expressions
- Java - Sending Email
- Java - Applet Basics
- Java - Javadoc Comments
- Java - Autoboxing and Unboxing
- Java - File Mismatch Method
- Java - REPL (JShell)
- Java - Multi-Release Jar Files
- Java - Private Interface Methods
- Java - Inner Class Diamond Operator
- Java - Multiresolution Image API
- Java - Collection Factory Methods
- Java - Module System
- Java - Nashorn JavaScript
- Java - Optional Class
- Java - Method References
- Java - Functional Interfaces
- Java - Default Methods
- Java - Base64 Encode Decode
- Java - Switch Expressions
- Java - Teeing Collectors
- Java - Microbenchmark
- Java - Text Blocks
- Java - Dynamic CDS archive
- Java - Z Garbage Collector (ZGC)
- Java - Null Pointer Exception
- Java - Packaging Tools
- Java - Sealed Classes
- Java - Record Classes
- Java - Hidden Classes
- Java - Pattern Matching
- Java - Compact Number Formatting
- Java - Garbage Collection
- Java - JIT Compiler
Java Miscellaneous
- Java - Recursion
- Java - Regular Expressions
- Java - Serialization
- Java - Strings
- Java - Process API Improvements
- Java - Stream API Improvements
- Java - Enhanced @Deprecated Annotation
- Java - CompletableFuture API Improvements
- Java - Streams
- Java - Datetime Api
- Java 8 - New Features
- Java 9 - New Features
- Java 10 - New Features
- Java 11 - New Features
- Java 12 - New Features
- Java 13 - New Features
- Java 14 - New Features
- Java 15 - New Features
- Java 16 - New Features
Java APIs & Frameworks
Java Class References
- Java - Scanner Class
- Java - Arrays Class
- Java - Strings
- Java - Date & Time
- Java - ArrayList
- Java - Vector Class
- Java - Stack Class
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - The IdentityHashMap Class
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet Class
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection Interface
- Java - Array Methods
Java Useful Resources
Java - Reentrant Monitor
Reentrant Monitor in Java
ReetrantLock is a class that implements Lock Interface. It provides the synchronization feature with great flexibility which is why it is the most used lock class in Java. It is necessary for the reliable and fair working of thread. Here, threads are small sub-processes of a big operation. In this article, we are going to learn ReetrantLock and how they manage threads so that they can work efficiently.
Working of ReetrantLock
When multiple threads try to access a shared resource then, ReetrantLock restricts access to a single thread at a time through lock() and unlock() methods. Suppose there are three people trying to book a train ticket. At the same time, all three people will try to access the booking system, it may happen that two people end up booking the same seat. Reetrant Lock can handle this situation.
First, all three people will request to acquire the booking system through tryLock() method. When one acquires the booking system then, it restricts the particular seat booking through lock() method. After booking, the person will call the unlock() method to release the acquired lock. Till the resources are busy other people will wait in a queue for their turn and after the release of lock they will come in a runnable state.
ReetrantLock tries to provide locks in a fair manner. We can set for how long a thread can acquire lock and also, it ensures that a thread with the longest wait time may get access to lock first. By default the locks are unfair, to make it fair we need to pass Boolean value true in its constructor.
Syntax
ReentrantLock nameOflock = new ReentrantLock(); // by default false Or, ReentrantLock nameOflock = new ReentrantLock(true); // we can make it true
The locks are explicit and can lock or unlock in any order. A single thread can ask for the lock multiple times that's the reason the name of lock is Reentrant. We can count the number of times a lock is acquired by using getHoldCount() method.
Multithreading Without Reentrant Lock
The following example illustrates the multithreading witout use of Reetrant Lock in above code. We've created a class Thrd with a method operation() to perform a given task. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example of Multithreading Without Reentrant Lock
package com.tutorialspoint; class Thrd { static void operation(int data) { for(int i = 1; i <= 4; i++) { System.out.println(data++); } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); // method calling } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); // method calling } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); // method calling } } public class TestThread { public static void main(String args[]) { // creating object for thread class Thrd1 oprt1 = new Thrd1(); Thrd2 oprt2 = new Thrd2(); Thrd3 oprt3 = new Thrd3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } }
This produces a different result every time you run this program −
Output
1 2 3 4 10 11 12 13 5 6 7 8
Multithreading With Reentrant Lock
The following example illustrates the use of Reetrant Lock in above code. We've created a class Thrd and inside this thread, we've defined an object of ReentrantLock. A method operation() store the Boolean value of tryLock() method to a variable named lockAcquired which will check if lock gets acquired by any thread or not. If the lock is acquired lock is given to that thread using lock() method and then the thread start performing the given task. The task will be performed in the try block and the lock will be released in the finally block using unlock() method. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example of Multithreading With Reentrant Lock
package com.tutorialspoint; import java.util.concurrent.locks.ReentrantLock; class Thrd { // creating object of ReentrantLock class private static ReentrantLock lockr = new ReentrantLock(); static void operation(int data) { // give access to lock boolean lockAcquired = lockr.tryLock(); if (lockAcquired) { try { lockr.lock(); // giving lock to thread for(int i = 1; i <= 4; i++) { System.out.println(data++); } // checking lock count System.out.println("Count of Lock: " + lockr.getHoldCount()); } finally { lockr.unlock(); // unlocking the lock } } else { System.out.println("I am in else block"); } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); // method calling } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); // method calling } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); // method calling } } public class TestThread { public static void main(String args[]) { // creating object for thread class Thrd1 oprt1 = new Thrd1(); Thrd2 oprt2 = new Thrd2(); Thrd3 oprt3 = new Thrd3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } }
This produces a different result every time you run this program −
Output
I am in else block 5 6 7 8 Count of Lock: 2 I am in else block
Multithreading With Reentrant Lock as True
The following example illustrates the use of Reetrant Lock in above code. We've created a class Thrd and inside this thread, we've defined an object of ReentrantLock with fair value as true. A method operation() store the Boolean value of tryLock() method to a variable named lockAcquired which will check if lock gets acquired by any thread or not. If the lock is acquired lock is given to that thread using lock() method and then the thread start performing the given task. The task will be performed in the try block and the lock will be released in the finally block using unlock() method. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example of Multithreading With Reentrant Lock as True
package com.tutorialspoint; import java.util.concurrent.locks.ReentrantLock; class Thrd { // creating object of ReentrantLock class private static ReentrantLock lockr = new ReentrantLock(true); static void operation(int data) { // give access to lock boolean lockAcquired = lockr.tryLock(); if (lockAcquired) { try { lockr.lock(); // giving lock to thread for(int i = 1; i <= 4; i++) { System.out.println(data++); } // checking lock count System.out.println("Count of Lock: " + lockr.getHoldCount()); } finally { lockr.unlock(); // unlocking the lock } } else { System.out.println("I am in else block"); } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); // method calling } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); // method calling } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); // method calling } } public class TestThread { public static void main(String args[]) { // creating object for thread class Thrd1 oprt1 = new Thrd1(); Thrd2 oprt2 = new Thrd2(); Thrd3 oprt3 = new Thrd3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } }
This produces a different result every time you run this program −
Output
I am in else block I am in else block 5 6 7 8 Count of Lock: 2