The problems with treditional synchronized keyword
1: We are not heaving any flexibility to try for a lock without waiting.
2: There is no way to specify maximum waiting time for a thread to get lock so thread will wait untill getting the lock which may creates performance problems and cause deadlock.
3:If 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
The synchronize keyword is compulsory either at method level or within the method and it is not possible to use across multiple methods.
To overcome these problems sun people introduced java.util.concurrent.locks package in 1.5 version. It also provide several enhancement to the programmer to provide more control on concurrency.
Lock Interface :
Lock object is similar to implicit lock acquired by a thread to executes synchronized method or synchronized block. Lock implementations provides more extensive operation than traditional implicit locks.
Important methods of Lock Interface
void lock()
We can use this method to acquired a lock if lock is already available then immidialtly current thread can get this lock. If the lock is not already available then it will wait untill get the lock.
It is exactly same behaviour of traditional synchronized keyword.
boolean tryLock()
To acquire the lock without waiting. If the lock is available then the threads acquir that lock and returns true. If lock is not available then this method returns falls then continue its execution without waiting.
In this case, thread naver be entered into waiting state.
if(l.tryLock()) {
perform safe operation
}else {
perform alternate operation
}
tryLock(long time, TimeUnit unit)
If lock is available then te 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:
TimeUnit is an Enum present in java.util.concurrent package.
public static final java.util.concurrent.TimeUnit NANOSECONDS;
public static final java.util.concurrent.TimeUnit MICROSECONDS;
public static final java.util.concurrent.TimeUnit MILLISECONDS;
public static final java.util.concurrent.TimeUnit SECONDS;
public static final java.util.concurrent.TimeUnit MINUTES;
public static final java.util.concurrent.TimeUnit HOURS;
public static final java.util.concurrent.TimeUnit DAYS;
void lockInterruptibly()
Acquirs the lock if it is available and returns immidiatly. If the lock is not available then it will wait
while waiting if thread is interrupted then thread will not get the lock.
void unlock()
to call this method compulsory current thread should be owner of the lock, otherwise we will get runtime exception saying illegelMOnitor Exception
Class ReentrantLock
It is the implementation class of Lock interface and it is the direct child class of Object. Here Reentrant means a thread can acquir same lock multiple times without any issue. Internally ReentrantLock increment thread personal acount whenver we call lock method & decrement counts value whenever thread call unlock() method & lock will be relases when count reached zero.
Constructors
ReentrantLock l=new ReentrantLock();
It creates an instance of ReentrantLock.
ReentrantLock l=new ReentrantLock(Boolean fairness);
It creates an instance of ReentrantLock with given fairness policy. If the fairness is true then longest waiting thread will acquir the lock if it is available. It means it follows first come first serve policy. If fairness is false then which waiting thread will the chance we can not expect. The default value for the fairness is false.
Which of the following declarations are equal.
1:ReentrantLock l=new ReentrantLock();
2:ReentrantLock l=new ReentrantLock(true);
3:ReentrantLock l=new ReentrantLock(false);
4: All the above
Ans 1st & 3rd
Important methods of ReentrantLock class
public void lock()
public void lockInterruptibly()
public boolean tryLock()
public boolean tryLock(long timeout,TimeUnit unit)
public void unlock()
public int getHoldCount()
public boolean isHeldByCurrentThread()
public final boolean isFair()
public final boolean hasQueuedThreads()
public final boolean hasQueuedThread(Thread thread)
public final int getQueueLength()
protected Collection<Thread> getQueuedThreads()
protected Thread getOwner()