Using Timeout to avoid deadlock in Java multithreading

无人久伴 提交于 2019-12-18 13:19:14

问题


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 ?


回答1:


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



回答2:


may this help,

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



回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/13741479/using-timeout-to-avoid-deadlock-in-java-multithreading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!