The problems with traditional synchronized keyword:
1. We are not having any flexibity to try for the lock without waiting.
2. There is no way to specify maximum waiting time for a Thread to get lock so that Thread will wait until getting the lock which may create performance problem and cause deadlock.
3. If a Thread releases the lock, then which waiting Thread will get that lock we are not having any control on this.
4. There is no API to list out all waiting Threads for a lock.
5. The synchronized compulsory we have to use either or method level or with in the method and it is not possible to use across the multiple methods.
To overcome these problems, java people introduced java.util.concurrent.locks package in jdk1.5 version It also provides several enhancements to the programmer to provide more control on concurrency.
Lock interface:
Lock object is similar to implicit lock acquired by a Thread to execute synchronized method or synchronized block.
Lock implementations provide more extensive operations than traditional implicit locks.
Important methods of Lock interface:
void lock(): we can use this method to acquire a lock. If the lock is already available then immediately current Thread will get that lock. If the lock is not already available then it will wait until getting the lock. It is same behavior of traditional synchronized keyword.
boolean tryLock(): to acquire the lock without waiting. If the lock is available then the Thread acquires the lock and returns the true. if the lock is not available then the lock returns false and can continue its execution without waiting. In this case Thread will never be entered into waiting state.
3. boolean tryLock(long time, TimeUnit unit):
if the lock is available then the Thread will get the lock and continue its execution. if the lock is not available then the Thread will wait until specified amount of time still if the lock is not available then Thread can continue its execution.
TimeUnit is an enum present in java.util.concurrent package;
4. void lockinterruptibly(): acquires the lock if it is available and returns immediately. If the lock is not available then it will wait. While waiting if the Thread is interrupted then Thread won’t get the lock.
5. void unlock(): To call this method compulsory current Thread should be owner of that lock otherwise we will get runtime exceptions saying IllegalMonitorStateException.
ReentrantLock():
- It is the implementation class of Lock interface and it is direct child class of Object.
- Reentrant means a Thread can acquire same lock multiple times without any issue.
- Internally Reentrant lock implements Threads personal count whenever we called lock(0 method and decrements count value whenever thread call unlock() method and lock will released whenever count reaches 0.
Constructors:
creates an instance of ReentrantLock
creates ReentrantLock with a given fairness policy.
If the fairness is true then longest waiting thread can acquire the lock if it is available i.e., it follows first come first serve policy.
If the fairness is false then which waiting Thread will get chance we cant expect.
Note: the default value for fairness is false.
which of the following declarations are equal?
[1]. ReentranLock l = new ReentrantLock();
[2]. ReentranLock l = new ReentrantLock(true);
[3]. ReentranLock l = new ReentrantLock(false);
[4]. All the above
Important methods of ReentrantLock:
if we comment line-1 and line-2 then the Threads will be executed simultaneously and we will get irregular output
if we are not comment line-1 and line-2 then the Threads will be executed one by one and we will get regular output
Output:
First Thread...got lock and performing safe operations
Second Thread...unable to get lock and hence performing alternative operations
Output:
First Thread...got lock
Second Thread...unable to get lock and will try again
First Thread...releases lock
Second Thread...got lock
Second Thread...releases lock
0 Comments