The traditional way to achieve thread synchronization in Java is by the use of synchronized keyword. While it provides a certain basic synchronization, the synchronized keyword is quite rigid in its use. For example, a thread can take a lock only once. Synchronized blocks don’t offer any mechanism of a waiting queue and after the exit of one thread, any thread can take the lock. This could lead to starvation of resources for some other thread for a very long period of time.
Reentrant Locks are provided in Java to provide synchronization with greater flexibility.
What are Reentrant Locks?
The ReentrantLock class implements the Lock interface and provides
synchronization to methods while accessing shared resources. The code
which manipulates the shared resource is surrounded by calls to lock and
unlock method. This gives a lock to the current working thread and
blocks all other threads which are trying to take a lock on the shared
resource.public class ThreadsExample implements Runnable {
static int counter = 1; // a global counter
static ReentrantLock counterLock = new ReentrantLock(true); // enable fairness policy
static void incrementCounter(){
counterLock.lock();
// Always good practice to enclose locks in a try-finally block
try{
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
}finally{
counterLock.unlock();
}
}
@Override
public void run() {
while(counter<1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
No comments:
Post a Comment