One of the strategy to avoid deadlock situation in Java Multithreading is using timeout.
Suppose, one thread has acquired lock on one resource and now waiting for lock on another resource. After certain time period if it can not acquire lock on resource2 then it should stop waiting for lock on resource2. Also it should release lock on resource1. Thus deadlocks will be avoided.
But how to implement it in Java ? How to explicitly "release" lock ? How to define timeout to wait for lock.
What is exact java commands and syntax. Any hello-worldish example please ?
Here is a contrived example with 2 locks and 2 threads that try to acquire them in different orders. Without the timeout, the code would deadlock.
public static void main(String[] args) throws Exception {
final ReentrantLock lock1 = new ReentrantLock();
final ReentrantLock lock2 = new ReentrantLock();
Runnable try1_2 = getRunnable(lock1, "lock 1", lock2, "lock 2");
Runnable try2_1 = getRunnable(lock2, "lock 2", lock1, "lock 1");
new Thread(try1_2).start();
new Thread(try2_1).start();
}
private static Runnable getRunnable(final ReentrantLock lock1, final String lock1Name, final ReentrantLock lock2, final String lock2Name) {
return new Runnable() {
@Override
public void run() {
try {
if (lock1.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(lock1Name + " acquired in thread " + Thread.currentThread());
if (lock2.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(lock2Name + " acquired in thread " + Thread.currentThread());
Thread.sleep(2000);
} else {
System.out.println("Could not acquire "+lock2Name + " in thread " + Thread.currentThread());
lock1.unlock();
System.out.println(lock1Name + " released in thread " + Thread.currentThread());
}
} else {
System.out.println("Could not acquire " + lock1Name + " in thread " + Thread.currentThread());
}
} catch (InterruptedException e) {
//you should not ignore it
} finally {
if (lock1.isHeldByCurrentThread()) lock1.unlock();
if (lock2.isHeldByCurrentThread()) lock2.unlock();
}
}
};
}
may this help,
Lock lock = null;
lock=....;
if (lock.tryLock(15L, TimeUnit.SECONDS)) {
try {
........
} finally {
lock.unlock();
}
} else {
// do sumthing
}
Lock in Java
Use tryLock(timeout, timeunits);
Acquires the lock if it is free within the given waiting time and the
current thread has not been interrupted. If the lock is available this
method returns immediately with the value true
.
If the lock is not
available then the current thread becomes disabled for thread
scheduling purposes and lies dormant until one of three things
happens:
The lock is acquired by the current thread;
or Some other thread
interrupts the current thread, and interruption of lock acquisition is
supported;
or The specified waiting time elapses
In the Java 8+ Concurrency API you can set an explicit time for a lock
to wait when it's condition is set:
private Lock lock = new ReentrantLock();
private Condition myCondition = lock.newCondition();
try{
myCondition.await(1200L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println((e);
} finally{
lock.unlock();
}
The lock will wait until it receives a signal()
or signalAll()
from another thread or until the time of 1.2 seconds expires.