Java多线程 开发中避免死锁的八种方法

摘要:
1.设置超时时间使用JUC包中的Lock接口提供的tryLock方法.该方法在获取锁的时候,可以设置超时时间,如果超过了这个时间还没拿到这把锁,那么就可以做其他的事情,而不是像synchronized如果没有拿到锁会一直等待下去.booleantryLock(longtime,TimeUnitunit)throwsInterruptedException;造成超时的原因有很多种:发生了死锁,线程进

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: https://javaweixin6.blog.csdn.net/
 * 创建时间: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失败, 已重试  "  )  ;  }  }  catch  

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇BLDC开发笔记1.原理及硬件部分Maven环境变量配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

动态创建线程(多线程)处理大量数据

1 import java.util.List; 2 import java.util.concurrent.CountDownLatch; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 public cl...

Android Handler与多线程

本文首先解释一下handler是用来干嘛的,然后通过例子介绍其在多线程中的应用。 什么是Handler      handler通俗一点讲就是用来在各个进程之间发送数据的处理对象。在任何进程中,只要获得了另一个进程的handler则可以通过 handler.sendMessage(message)方法向那个进程发送数据。基于这个机制,我们在处理多线程的时...

perl多线程使用

原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun <<=========================threads===========================>> #!/usr/bin/perl use threads ('yield',...

微信定时获取token

为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台开放了许多接口,包括自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口等,开发者在调用这些接口时,都需要传入一个相同的参数access_token,它是公众账号的全局唯一票据,它是接口访问凭证。 access_token的有效期是7200秒(两小时),在有效期内,可以一直...

c# 线程的几种实现方式

1.匿名线程实时监控,随便写在一个方法内就可以了 new Thread(() => { while (implement) { try {...

.Net 调式案例—实验4 高CPU(High CPU)回顾

转载: https://www.cnblogs.com/softfair/archive/2008/03/03/dotnet-Debugging-Demos---Lab-4-HighCPU--Review.html   .Net 调式案例—实验4 高CPU(High CPU)回顾   现在开始第四个实验。 前面的案例和设置指导 请参看前面发布的文章。...