1. 设置超时时间

使用JUC包中的Lock接口提供的tryLock方法. 
该方法在获取锁的时候, 可以设置超时时间, 如果超过了这个时间还没拿到这把锁, 那么就可以做其他的事情, 而不是像 synchronized 如果没有拿到锁会一直等待下去.

boolean   tryLock   (   long  time  ,  TimeUnit unit  )   throws  InterruptedException  ;

造成超时的原因有很多种:发生了死锁, 线程进入了死循环, 线程逻辑复杂执行慢.

到了超时时间, 那么就获取锁失败, 就可以做一些记录操作, 例如 打印错误日志, 发送报警邮件,提示运维人员重启服务等等.

如下的代码演示了 使用tryLock 来避免死锁的案例. 
线程1 如果拿到了锁1 , 那么就在指定的800毫秒内去尝试拿到锁2, 如果两把锁都拿到了 , 那么就释放这两把锁. 如果在指定的时间内, 没有拿到锁2 , 那么就释放锁1 .

线程2 与线程1相反, 先去尝试拿到锁2, 如果拿到了, 就去在3s内尝试拿到锁1, 如果拿到了, 那么就释放锁1和2, 如果3s内没有拿到锁1, 那么释放锁2 .

package  com  .  thread  .  deadlock  ;   import  java  .  util  .  Random  ;   import  java  .  util  .  concurrent  .  TimeUnit  ;   import  java  .  util  .  concurrent  .  locks  .  Lock  ;   import  java  .  util  .  concurrent  .  locks  .  ReentrantLock  ;   /**
 * 类名称:TryLockDeadlock
 * 类描述:  使用lock接口提供的trylock 避免死锁
 *
 * @author: 
 * 创建时间:2020/9/12 17:23
 * Version 1.0
 */   public   class   TryLockDeadlock   implements   Runnable   {   int  flag  =   1   ;   //ReentrantLock 为可重入锁   static  Lock lock1  =   new   ReentrantLock   (   )   ;   static  Lock lock2  =   new   ReentrantLock   (   )   ;   public   static   void   main   (  String  [   ]  args  )   {   // 创建两个线程 给出不同的flag  并启动  TryLockDeadlock r1  =   new   TryLockDeadlock   (   )   ;  TryLockDeadlock r2  =   new   TryLockDeadlock   (   )   ;  r1  .  flag  =   1   ;  r2  .  flag  =   0   ;   new   Thread   (  r1  )   .   start   (   )   ;   new   Thread   (  r2  )   .   start   (   )   ;   }   @Override   public   void   run   (   )   {   for   (   int  i  =   0   ;  i  <   100   ;  i  ++   )   {   if   (  flag  ==   1   )   {   //先获取锁1  再获取锁2   try   {   //给锁1 800毫秒与获取锁, 如果拿到锁, 返回true, 反之返回false   if   (  lock1  .   tryLock   (   800   ,  TimeUnit  .  MICROSECONDS  )   )   {  System  .  out  .   println   (   "线程1获取到了锁1  "   )   ;   //随机的休眠  Thread  .   sleep   (   new   Random   (   )   .   nextInt   (   1000   )   )   ;   if   (  lock2  .   tryLock   (   800   ,  TimeUnit  .  MICROSECONDS  )   )   {  System  .  out  .   println   (   "线程1获取到了锁2  "   )   ;  System  .  out  .   println   (   " 线程1 成功获取了两把锁   "   )   ;   //释放两把锁, 退出循环  lock2  .   unlock   (   )   ;  lock1  .   unlock   (   )   ;   break   ;   }   else   {  System  .  out  .   println   (   " 线程1尝试获取锁2 失败, 已经重试  "   )   ;   //释放锁1  lock1  .   unlock   (   )   ;   //随机的休眠  Thread  .   sleep   (   new   Random   (   )   .   nextInt   (   1000   )   )   ;   }   }   else   {  System  .  out  .   println   (   " 线程1 获取锁1失败, 已重试  "   )   ;   }   }