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 lockRefer to Java Tutorials page for more tutorials.
0 comments:
Post a Comment