Reentrant lock
- Eclipse: Oxygen
- Java: 1.8
The Reentrant lock is a mutually exclusive lock. This lock means that the lock can be accessed by the thread that owns it or controls it more than once. Therefore, if any thread has access to that lock, no other thread, except that thread, can use that. This is the specific use of that lock.
Here we show how to use ReentrantLock in Java. Reentrant locking is an alternative form of locking apart from the implicit locking provided by keyword synchronized in Java.
In the following program, we create a ReentrantLock object. In the main method, we create two threads to execute and pass the lock to the object. Use the lock () method to acquire the lock on the shared resource. After completing the job, call the unlock() method to release the lock.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class App { static int counter = 0; static Lock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { @Override public void run() { lock.lock(); for (int i = 1; i <= 1000; i++) { App.counter++; } lock.unlock(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { lock.lock(); for (int i = 1; i <= 1000; i++) { App.counter++; } lock.unlock(); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("The final value of counter is " + App.counter); } } |
Output
1 |
The final value of counter is 2000 |
A finally block contains all the crucial declarations that must be executed, whether an exception occurs or not. The declarations present in this block will always be executed regardless of whether an exception occurs in the try block or not.
It is optional, a try-catch block is sufficient for exception handling, however, if you place a finally block then it will always run after the execution of try block.
Suppose that within for loop we find an exception in that type of scenario lock will not be released because we will not be able to call the lock.unlock() method. In that situation, we will use finally block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public class App { static int counter = 0; static Lock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { @Override public void run() { lock.lock(); try { for (int i = 1; i <= 1000; i++) { App.counter++; } } finally { lock.unlock(); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { lock.lock(); try { for (int i = 1; i <= 1000; i++) { App.counter++; } } finally { lock.unlock(); } } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("The final value of counter is " + App.counter); } } |
Contributed by: Poonam Tomar