Tutorial

Java Lock Example - ReentrantLock

Published on August 3, 2022
author

Pankaj

Java Lock Example - ReentrantLock

Welcome to Java Lock example tutorial. Usually when working with multi-threaded environment, we use synchronized for thread safety.

Java Lock

java lock, java lock example, ReentrantLock in Java, java locks Most of the times, synchronized keyword is the way to go but it has some shortcomings that lead the way to inclusion of Lock API in Java Concurrency package. Java 1.5 Concurrency API came up with java.util.concurrent.locks package with Lock interface and some implementation classes to improve the Object locking mechanism. Some important interfaces and classes in Java Lock API are:

  1. Lock: This is the base interface for Lock API. It provides all the features of synchronized keyword with additional ways to create different Conditions for locking, providing timeout for thread to wait for lock. Some of the important methods are lock() to acquire the lock, unlock() to release the lock, tryLock() to wait for lock for a certain period of time, newCondition() to create the Condition etc.

  2. Condition: Condition objects are similar to Object wait-notify model with additional feature to create different sets of wait. A Condition object is always created by Lock object. Some of the important methods are await() that is similar to wait() and signal(), signalAll() that is similar to notify() and notifyAll() methods.

  3. ReadWriteLock: It contains a pair of associated locks, one for read-only operations and another one for writing. The read lock may be held simultaneously by multiple reader threads as long as there are no writer threads. The write lock is exclusive.

  4. ReentrantLock: This is the most widely used implementation class of Lock interface. This class implements the Lock interface in similar way as synchronized keyword. Apart from Lock interface implementation, ReentrantLock contains some utility methods to get the thread holding the lock, threads waiting to acquire the lock etc. synchronized block are reentrant in nature i.e if a thread has lock on the monitor object and if another synchronized block requires to have the lock on the same monitor object then thread can enter that code block. I think this is the reason for the class name to be ReentrantLock. Let’s understand this feature with a simple example.

    public class Test{
    
    public synchronized foo(){
        //do something
        bar();
      }
    
      public synchronized bar(){
        //do some more
      }
    }
    

    If a thread enters foo(), it has the lock on Test object, so when it tries to execute bar() method, the thread is allowed to execute bar() method since it’s already holding the lock on the Test object i.e same as synchronized(this).

Java Lock Example - ReentrantLock in Java

Now let’s see a simple example where we will replace synchronized keyword with Java Lock API. Let’s say we have a Resource class with some operation where we want it to be thread-safe and some methods where thread safety is not required.

package com.journaldev.threads.lock;

public class Resource {

	public void doSomething(){
		//do some operation, DB read, write etc
	}
	
	public void doLogging(){
		//logging, no need for thread safety
	}
}

Now let’s say we have a Runnable class where we will use Resource methods.

package com.journaldev.threads.lock;

public class SynchronizedLockExample implements Runnable{

	private Resource resource;
	
	public SynchronizedLockExample(Resource r){
		this.resource = r;
	}
	
	@Override
	public void run() {
		synchronized (resource) {
			resource.doSomething();
		}
		resource.doLogging();
	}
}

Notice that I am using synchronized block to acquire the lock on Resource object. We could have created a dummy object in the class and used that for locking purpose. Now let’s see how we can use java Lock API and rewrite above program without using synchronized keyword. We will use ReentrantLock in java.

package com.journaldev.threads.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConcurrencyLockExample implements Runnable{

	private Resource resource;
	private Lock lock;
	
	public ConcurrencyLockExample(Resource r){
		this.resource = r;
		this.lock = new ReentrantLock();
	}
	
	@Override
	public void run() {
		try {
			if(lock.tryLock(10, TimeUnit.SECONDS)){
			resource.doSomething();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			//release lock
			lock.unlock();
		}
		resource.doLogging();
	}

}

As you can see that, I am using tryLock() method to make sure my thread waits only for definite time and if it’s not getting the lock on object, it’s just logging and exiting. Another important point to note is the use of try-finally block to make sure lock is released even if doSomething() method call throws any exception.

Java Lock vs synchronized

Based on above details and program, we can easily conclude following differences between Java Lock and synchronization.

  1. Java Lock API provides more visibility and options for locking, unlike synchronized where a thread might end up waiting indefinitely for the lock, we can use tryLock() to make sure thread waits for specific time only.
  2. Synchronization code is much cleaner and easy to maintain whereas with Lock we are forced to have try-finally block to make sure Lock is released even if some exception is thrown between lock() and unlock() method calls.
  3. synchronization blocks or methods can cover only one method whereas we can acquire the lock in one method and release it in another method with Lock API.
  4. synchronized keyword doesn’t provide fairness whereas we can set fairness to true while creating ReentrantLock object so that longest waiting thread gets the lock first.
  5. We can create different conditions for Lock and different thread can await() for different conditions.

That’s all for Java Lock example, ReentrantLock in java and a comparative analysis with synchronized keyword.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial
Tags:

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 10, 2013

I really appreciate your effort on putting the consolidated information in one place in nice manner… thank you very much.

- Nagaraju

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    February 24, 2014

    Hello Friend, Just let me know if I am wrong- I thing lock.tryLock(10, TimeUnit.SECONDS); in run method i trying to access lock on ConcurrencyLockExample object instead of Resource object. If you want to get lock on Resource object than Lock lock= new Reentrant(); should be added in Resource Class;

    - Dharmendra

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    February 24, 2014

    Hi Dharmendra, We don’t want lock on Resource object, we want lock on the code that is executing resource method for thread safety. So lock.tryLock() will get the lock on the object and then execute the doSomething() method. While executing if some other thread is also asking for the lock, that thread will wait until the first thread is finished executing the doSomething() method and has released the lock. In real life, we don’t always has control on the Resource objects and it’s the responsibility of the caller to look after thread safety. If the threads are not involved, then having locking mechanism in the Resource classes will be an extra overhead to the system.

    - Pankaj

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    September 20, 2014

    Thanks very much for this great article. However, I am not clear on your comment. “So lock.tryLock() will get the lock on the object and then execute the doSomething() method.” I think tryLock will acquire lock on runnable instance itself rather than resource. I somehow don’t see any point where an object of runnable would need to acquire lock on a part (code block) of itself.

    - Ken

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      February 26, 2014

      Hi, I like to thank you for providing such a good explaination with simple example.

      - amit nandode

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        February 27, 2014

        Good

        - Vijay Yadav

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          April 8, 2014

          Hi, I guess you did a mistake here: As you can see that, I am using tryLock() method to make sure my thread waits only for definite time and if it’s not getting the lock on object, it’s just logging and exiting. Since tryLock returns false if the lock hasn’t been acquired and doesn’t raise an exception, you should place resource.doSomething() in IF block.

          - 3biga

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          April 8, 2014

          Thanks for the observation, you are right. I have updated the program.

          - Pankaj

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            April 9, 2014

            Hi Pankaj, Can you please also explain the different Condition of lock & Lock Fairness with an example.

            - HIMANSU NAYAK

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              April 10, 2014

              Hi Pankaj, I created a test class to run this code. public class CocurrencyLockMain { public static void main(String… args) { Resource resource = new Resource(); new Thread(new ConcurrencyLock(resource)).start(); new Thread(new ConcurrencyLock(resource)).start(); } } i was expecting the second thread should wait till the first thread execution completed but both the thread were running simultaneously. Can you please explain what is wrong in my understanding.

              - HIMANSU NAYAK

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              April 10, 2014

              Sorry i forget move the lock from instance to class reference.

              - HIMANSU NAYAK

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              April 9, 2021

              Can you post the entire working example in Java with main() method

              - Deepak Lalchandani

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                April 18, 2014

                Hey just wanted to know why do we use ReadLock…? when multiple threads are allowed so what is need of ReadLock…? access it without any lock.

                - Hrishi

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                May 6, 2014

                If I understand correctly, ReadWriteLock will allow multiple thread to read the Resource as long as there is no Writer Thread modifying the same Resource. Basically, it seems like, if there is some thread modifying the Resource, it may not be good idea to read either. I believe, this’s not achievable using Synchronized the moment we Synchronize the blocks of Read and Write on the same object it would not even allow to read by multiple thread at the same time.

                - Bhaskar

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  May 6, 2014

                  Thanks Pankaj for this blog. I could get a brief information about the Lock API. It’s simple and good. It may become more useful if there is an example for each of those cases: Condition, ReadWriteLock and ReentrantLock.

                  - Bhaskar

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    June 17, 2014

                    Thanks a lot! Finally understood Re-entrant lock!

                    - Suhita

                      JournalDev
                      DigitalOcean Employee
                      DigitalOcean Employee badge
                      August 26, 2014

                      Not checked with code, but I think your finally block actually needs to be finally { if( lock.isHeldByCurrentThread() { lock.unlock(); } otherwise there is a risk of an IllegalMonitorStateException if an exception was thrown due to tryLock being interrupted (the InterruptedException e you’re catching)

                      - J Saxton

                        JournalDev
                        DigitalOcean Employee
                        DigitalOcean Employee badge
                        October 9, 2014

                        Resource resource = new Resource(); ConcurrencyLockExample c = new ConcurrencyLockExample(resource); Thread t = new Thread(c, “My Thread”); Thread t1 = new Thread(c, “My Thread”); t.start(); t1.start(); I used above code to Test Lock function I found lock.tryLock(10, TimeUnit.MILLISECONDS) never return false;

                        - shailendra

                          JournalDev
                          DigitalOcean Employee
                          DigitalOcean Employee badge
                          November 4, 2014

                          Hi , How this ConcurrencyLockExample work as you are not sharing the lock across the threads ?.

                          - Bhagath Sagar

                            JournalDev
                            DigitalOcean Employee
                            DigitalOcean Employee badge
                            November 18, 2014

                            What happens if a thread waits for certain period, say 10 secs and not able to get lock. Will it not try to lock again? I think this may inconstant behavior

                            - shiva

                              JournalDev
                              DigitalOcean Employee
                              DigitalOcean Employee badge
                              November 18, 2014

                              Suppose there are 10 threads name like T1, T2,… T10. T1 is in running stage. All other threads T2,…T10 are in waiting stage. When T1 finish its operation, then any one of them(T2,…T10) will get chance to start working. If all the threads have same priority then which how to select the thread to start its operation?

                              - Prakash

                              JournalDev
                              DigitalOcean Employee
                              DigitalOcean Employee badge
                              May 18, 2015

                              If multiple threads having same priority then Thread Schedular will decide which thread to start ,It is Varient on JVM.

                              - praveen kumar

                                JournalDev
                                DigitalOcean Employee
                                DigitalOcean Employee badge
                                January 22, 2015

                                Thanks! Finally understated locks

                                - Lalita Kamde

                                  JournalDev
                                  DigitalOcean Employee
                                  DigitalOcean Employee badge
                                  April 11, 2015

                                  Do the locking outside of the try. You want to avoid throwing an IllegalMonitorStateException.

                                  - farrell2k

                                    JournalDev
                                    DigitalOcean Employee
                                    DigitalOcean Employee badge
                                    April 21, 2015

                                    Good Article.

                                    - Veranga

                                      JournalDev
                                      DigitalOcean Employee
                                      DigitalOcean Employee badge
                                      April 30, 2015

                                      Hi Pankaj, this demo i get a correct result ,i was expecting the second thread should wait till the first thread execution completed but both the thread were running simultaneously.

                                      - Wells Lee

                                        JournalDev
                                        DigitalOcean Employee
                                        DigitalOcean Employee badge
                                        August 24, 2015

                                        Thanks for the wonderful tutorial on Threads:) Simple and precise, upto point tutorial so far:) Thanks a ton:)

                                        - Gopinath

                                          JournalDev
                                          DigitalOcean Employee
                                          DigitalOcean Employee badge
                                          August 26, 2014

                                          Not checked with code, but I think your finally block actually needs to be finally { if( lock.isHeldByCurrentThread() { lock.unlock(); } otherwise there is a risk of an IllegalMonitorStateException if an exception was thrown due to tryLock being interrupted (the InterruptedException e you’re catching)

                                          - J Saxton

                                            JournalDev
                                            DigitalOcean Employee
                                            DigitalOcean Employee badge
                                            October 9, 2014

                                            Resource resource = new Resource(); ConcurrencyLockExample c = new ConcurrencyLockExample(resource); Thread t = new Thread(c, “My Thread”); Thread t1 = new Thread(c, “My Thread”); t.start(); t1.start(); I used above code to Test Lock function I found lock.tryLock(10, TimeUnit.MILLISECONDS) never return false;

                                            - shailendra

                                              JournalDev
                                              DigitalOcean Employee
                                              DigitalOcean Employee badge
                                              November 4, 2014

                                              Hi , How this ConcurrencyLockExample work as you are not sharing the lock across the threads ?.

                                              - Bhagath Sagar

                                                JournalDev
                                                DigitalOcean Employee
                                                DigitalOcean Employee badge
                                                November 18, 2014

                                                What happens if a thread waits for certain period, say 10 secs and not able to get lock. Will it not try to lock again? I think this may inconstant behavior

                                                - shiva

                                                  JournalDev
                                                  DigitalOcean Employee
                                                  DigitalOcean Employee badge
                                                  November 18, 2014

                                                  Suppose there are 10 threads name like T1, T2,… T10. T1 is in running stage. All other threads T2,…T10 are in waiting stage. When T1 finish its operation, then any one of them(T2,…T10) will get chance to start working. If all the threads have same priority then which how to select the thread to start its operation?

                                                  - Prakash

                                                    JournalDev
                                                    DigitalOcean Employee
                                                    DigitalOcean Employee badge
                                                    January 22, 2015

                                                    Thanks! Finally understated locks

                                                    - Lalita Kamde

                                                      JournalDev
                                                      DigitalOcean Employee
                                                      DigitalOcean Employee badge
                                                      April 11, 2015

                                                      Do the locking outside of the try. You want to avoid throwing an IllegalMonitorStateException.

                                                      - farrell2k

                                                        JournalDev
                                                        DigitalOcean Employee
                                                        DigitalOcean Employee badge
                                                        April 21, 2015

                                                        Good Article.

                                                        - Veranga

                                                          JournalDev
                                                          DigitalOcean Employee
                                                          DigitalOcean Employee badge
                                                          April 30, 2015

                                                          Hi Pankaj, this demo i get a correct result ,i was expecting the second thread should wait till the first thread execution completed but both the thread were running simultaneously.

                                                          - Wells Lee

                                                            JournalDev
                                                            DigitalOcean Employee
                                                            DigitalOcean Employee badge
                                                            August 24, 2015

                                                            Thanks for the wonderful tutorial on Threads:) Simple and precise, upto point tutorial so far:) Thanks a ton:)

                                                            - Gopinath

                                                              Try DigitalOcean for free

                                                              Click below to sign up and get $200 of credit to try our products over 60 days!

                                                              Sign up

                                                              Join the Tech Talk
                                                              Success! Thank you! Please check your email for further details.

                                                              Please complete your information!

                                                              Become a contributor for community

                                                              Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                                                              DigitalOcean Documentation

                                                              Full documentation for every DigitalOcean product.

                                                              Resources for startups and SMBs

                                                              The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                                                              Get our newsletter

                                                              Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                                                              New accounts only. By submitting your email you agree to our Privacy Policy

                                                              The developer cloud

                                                              Scale up as you grow — whether you're running one virtual machine or ten thousand.

                                                              Get started for free

                                                              Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                                                              *This promotional offer applies to new accounts only.