Kaushik Lele
Kaushik Lele

Reputation: 6637

Using Timeout to avoid deadlock in Java multithreading

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 ?

Upvotes: 12

Views: 30927

Answers (4)

Stuart Cardall
Stuart Cardall

Reputation: 2447

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.

Upvotes: 3

assylias
assylias

Reputation: 328598

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();
            }
        }
    };
}

Upvotes: 10

Narendra Pathai
Narendra Pathai

Reputation: 41945

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

Upvotes: 3

arvin_codeHunk
arvin_codeHunk

Reputation: 2390

may this help,

Lock lock = null;
lock=....;
if (lock.tryLock(15L, TimeUnit.SECONDS)) {
    try {
       ........
    } finally {
        lock.unlock();
    }
} else {
      // do sumthing
}

Upvotes: 4

Related Questions