使用Timeout避免Javamultithreading中的死锁

避免Javamultithreading中死锁情况的策略之一是使用超时。 假设,一个线程已获得对一个资源的锁定,现在正在等待另一个资源上的锁定。 经过一段时间后,如果无法获取资源2的锁定,则应该停止等待资源2上的锁定。 它也应该释放对resource1的锁定。 因此将避免死锁。

但是如何在Java中实现它? 如何明确“释放”锁定? 如何定义等待锁的超时。

什么是精确的java命令和语法。 请问任何问候世界的例子吗?

这是一个人为的例子,有2个锁和2个线程,试图以不同的顺序获取它们。 没有超时,代码就会死锁。

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

可能这有帮助,

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

锁定Java

 Use tryLock(timeout, timeunits); 

如果在给定的等待时间空闲并且当前线程未被中断,则获取锁。 如果锁定可用,则此方法立即返回值true

如果锁不可用,那么当前线程将被禁用以进行线程调度,并且在发生以下三种情况之一之前处于hibernate状态:

锁定由当前线程获取 ;

或其他一些线程中断当前线程,并支持锁定获取中断;

或指定的等待时间过去了

在Java 8+ Concurrency API中,您可以设置lock在设置条件时等待的显式时间:

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

锁将一直等到它从另一个线程收到signal()signalAll()或直到1.2秒的时间到期。