Home | | Object Oriented Programming | | The Complete Reference Java | | Internet Programming | | Web Programming | Locks - java.util.concurrent.locks package

Chapter: Java The Complete Reference - The Java Library - The Concurrency Utilities

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Locks - java.util.concurrent.locks package

The java.util.concurrent.locks package provides support for locks, which are objects that offer an alternative to using synchronized to control access to a shared resource.

Locks

The java.util.concurrent.locks package provides support for locks, which are objects that offer an alternative to using synchronized to control access to a shared resource. In general, here is how a lock works. Before accessing a shared resource, the lock that protects that resource is acquired. When access to the resource is complete, the lock is released. If a second thread attempts to acquire the lock when it is in use by another thread, the second thread will suspend until the lock is released. In this way, conflicting access to a shared resource is prevented.

 

Locks are particularly useful when multiple threads need to access the value of shared data. For example, an inventory application might have a thread that first confirms that an item is in stock and then decreases the number of items on hand as each sale occurs. If two or more of these threads are running, then without some form of synchronization, it would be possible for one thread to be in the middle of a transaction when the second thread begins its transaction. The result could be that both threads would assume that adequate inventory exists, even if there is only sufficient inventory on hand to satisfy one sale. In this type of situation, a lock offers a convenient means of handling the needed synchronization.

The Lock interface defines a lock. The methods defined by Lock are shown in Table 28-1. In general, to acquire a lock, call lock( ). If the lock is unavailable, lock( ) will wait. To release a lock, call unlock( ). To see if a lock is available, and to acquire it if it is, call tryLock( ). This method will not wait for the lock if it is unavailable. Instead, it returns true if the lock is acquired and false otherwise. The newCondition( ) method returns a Condition object associated with the lock. Using a Condition, you gain detailed control of the lock through methods such as await( ) and signal( ), which provide functionality similar to Object.wait( ) and Object.notify( ).

 

java.util.concurrent.locks supplies an implementation of Lock called ReentrantLock.

 

ReentrantLock implements a reentrant lock, which is a lock that can be repeatedly entered by the thread that currently holds the lock. Of course, in the case of a thread reentering a lock, all calls to lock( ) must be offset by an equal number of calls to unlock( ). Otherwise, a thread seeking to acquire the lock will suspend until the lock is not in use.

Method : Description

 

void lock( ) : Waits until the invoking lock can be acquired.

 

void lockInterruptibly( ) throws InterruptedException : Waits until the invoking lock can be acquired, unless interrupted.

 

Condition newCondition( ) : Returns a Condition object that is associated with the invoking lock.

 

boolean tryLock( ) : Attempts to acquire the lock. This method will not wait if the lock is unavailable. Instead, it returns true if the lock has been acquired and false if the lock is currently in use by another thread.

 

boolean tryLock(long wait, TimeUnit tu) throws InterruptedException :  ttempts to acquire the lock. If the lock is unavailable, this method will wait no longer than the period specified by wait, which is in tu units. It returns true if the lock has been acquired and false if the lock cannot be acquired within the specified period.

 

void unlock( ) : Releases the lock.


Table 28-1   The Lock Methods

The following program demonstrates the use of a lock. It creates two threads that access a shared resource called Shared.count. Before a thread can access Shared.count, it must obtain a lock. After obtaining the lock, Shared.count is incremented and then, before releasing the lock, the thread sleeps. This causes the second thread to attempt to obtain the lock. However, because the lock is still held by the first thread, the second thread must wait until the first thread stops sleeping and releases the lock. The output shows that access to Shared.count is, indeed, synchronized by the lock.

 

 

// A simple lock example.

 

import java.util.concurrent.locks.*;

 

class LockDemo {

 

public static void main(String args[]) { ReentrantLock lock = new ReentrantLock();

 

new LockThread(lock, "A"); new LockThread(lock, "B");

 

}

 

}

 

    //A shared resource.

    class Shared {

static int count = 0;

 

}

 

    //A thread of execution that increments count.

    class LockThread implements Runnable {

 

String name; ReentrantLock lock;

 

LockThread(ReentrantLock lk, String n) { lock = lk;

 

name = n;

 

new Thread(this).start();

 

}

 

public void run() { System.out.println("Starting " + name);

 

try {

 

// First, lock count.

 

System.out.println(name + " is waiting to lock count."); lock.lock();

 

System.out.println(name + " is locking count.");

 

Shared.count++;

 

System.out.println(name + ": " + Shared.count);

 

// Now, allow a context switch -- if possible.

System.out.println(name + " is sleeping.");

 

Thread.sleep(1000);

 

} catch (InterruptedException exc) { System.out.println(exc);

 

} finally { // Unlock

 

System.out.println(name + " is unlocking count."); lock.unlock();

 

}

 

}

 

}

 

The output is shown here. (The precise order in which the threads execute may vary.)

 

Starting A

 

A is waiting to lock count.

 

A is locking count.

 

A: 1

 

A is sleeping.

 

Starting B

 

B is waiting to lock count.

 

A is unlocking count.

 

B is locking count.

 

B: 2

 

B is sleeping.

 

B is unlocking count.

 

java.util.concurrent.locks also defines the ReadWriteLock interface. This interface specifies a lock that maintains separate locks for read and write access. This enables multiple locks to be granted for readers of a resource as long as the resource is not being written. ReentrantReadWriteLock provides an implementation of ReadWriteLock.

 

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.