StackStalk
  • Home
  • Java
    • Java Collection
    • Spring Boot Collection
  • Python
    • Python Collection
  • C++
    • C++ Collection
    • Progamming Problems
    • Algorithms
    • Data Structures
    • Design Patterns
  • General
    • Tips and Tricks

Monday, September 22, 2014

Java ReentrantLock

 September 22, 2014     Java     No comments   

ReentrantLock Introduction

Lock provides a tool to control access to a shared resource in a multi-threaded environment. A lock provides access to only one thread at a time to the shared resource. Using synchronized methods and statements provides access to an implicit lock for an object. However in certain scenarios we might need access explicitly to the lock object for flexibility. ReentrantLock is a mutual exclusion lock similar to implicit lock provided by synchronized methods and statements but with additional flexibility.

Java ReentrantLock

Java supports Lock interface in the package java.util.concurrent.locks. ReentrantLock implements the Lock interface and provides the re-entrant mutual exclusive lock. Some of the key APIs of ReentrantLock are listed below.
  • ReentrantLock() - Creates ReentrantLock instance.
  • void lock() - Acquires the lock.
  • void unlock() - Releases the lock.
  • boolean tryLock() - Acquires the lock only if the lock is not held by another thread.
  • boolean isLocked() - Checks if lock is held by another thread.

Java ReentrantLock Example

In this example we have a producer and consumer task using a ReentrantLock object to protect a shared resource.
package com.sourcetricks.locks;

import java.util.concurrent.locks.ReentrantLock;

public class JavaLocksDemo {

    // Shared resources to be guarded
    private static int count = 0;
    
    // Producer thread. Counts up the resource.
    private static class ProducerTask implements Runnable {

      private ReentrantLock lock = null;
      
      ProducerTask(ReentrantLock lock) {
        this.lock = lock;
      }
      
      @Override
      public void run() {       
          System.out.println("Producer requesting lock");
          lock.lock();
          System.out.println("Producer gets lock");
          for ( int i = 0; i < 5; i++ ) {
            count = count + 1;
            System.out.println("Counting up");
          }
          try {
            Thread.sleep(5000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println("Producer releases lock");
          lock.unlock();
      }
      
    }
    
    // Consumer thread. Counts down the resource.
    private static class ConsumerTask implements Runnable {

      private ReentrantLock lock = null;
      
      ConsumerTask(ReentrantLock lock) {
        this.lock = lock;
      }
      
      @Override
      public void run() {
          System.out.println("Consumer requesting lock");
          lock.tryLock();
          System.out.println("Consumer gets lock");
          for ( int i = 0; i < 5; i++ ) {
            count = count - 1;
            System.out.println("Counting down");
          }
          System.out.println("Consumer releases lock");         
          lock.unlock();
      }    
    }
    
  public static void main(String[] args) {
    ReentrantLock lock = new ReentrantLock();
    Thread producer = new Thread(new ProducerTask(lock));
    Thread consumer = new Thread(new ConsumerTask(lock));
    producer.start();
    consumer.start();
  }
}
This program produces the following output.
Producer requesting lock
Consumer requesting lock
Producer gets lock
Counting up
Counting up
Counting up
Counting up
Counting up
Producer releases lock
Consumer gets lock
Counting down
Counting down
Counting down
Counting down
Counting down
Consumer releases lock
Refer to Java Tutorials page for more tutorials.
  • Share This:  
Newer Post Older Post Home

0 comments:

Post a Comment

Follow @StackStalk
Get new posts by email:
Powered by follow.it

Popular Posts

  • Avro Producer and Consumer with Python using Confluent Kafka
    In this article, we will understand Avro a popular data serialization format in streaming data applications and develop a simple Avro Produc...
  • Monitor Spring Boot App with Micrometer and Prometheus
    Modern distributed applications typically have multiple microservices working together. Ability to monitor and manage aspects like health, m...
  • Server-Sent Events with Spring WebFlux
    In this article we will review the concepts of server-sent events and work on an example using WebFlux. Before getting into this article it ...
  • Implement caching in a Spring Boot microservice using Redis
    In this article we will explore how to use Redis as a data cache for a Spring Boot microservice using PostgreSQL as the database. Idea is to...
  • Python FastAPI microservice with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Spring Boot with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Getting started with Kafka in Python
    This article will provide an overview of Kafka and how to get started with Kafka in Python with a simple example. What is Kafka? ...
  • Getting started in GraphQL with Spring Boot
    In this article we will explore basic concepts on GraphQL and look at how to develop a microservice in Spring Boot with GraphQL support. ...

Copyright © StackStalk