Java实现多线程死锁与资源限制

  介绍

本篇文章给大家分享的是有关Java实现多线程死锁与资源限制,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

锁是个非常有用的工具,运用场景非常多,因为它使用起来非常简单,而且易于理解。但同时它也会带来一些困扰,那就是可能会引起死锁,一旦产生死锁,就会造成系统功能不可用。

<强>死锁的概念

那什么是死锁呢?所谓死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

<强>死锁产生的必要条件

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0, P1, P2,···, Pn}中的P0正在等待一个P1占用的资源,P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

<强>死锁代码实例

公共类DeadLockDemo {
  私有静态字符串=癆";
  私有静态字符串B=癇";
  公共静态void main (String [] args) {
  新的DeadLockDemo () .deadLock ();
  }/* *
  *死锁
  * @author fuyuwei
  * 2017年5月13日下午9:27:32
  */私人无效死锁(){
  线程t1=新线程(新Runnable () {
  @SuppressWarnings (“static-access")
  @Override
  公共空间run () {
  同步(){
  尝试{
  Thread.currentThread () .sleep (2000);
  }捕捉(InterruptedException e) {
  e.printStackTrace ();
  }
  同步(B) {
  System.out.println (“1“);
  }
  }
  }
  });
  线程t2=新线程(新Runnable () {
  @Override
  公共空间run () {
  同步(B) {
  同步(){
  System.out.println (“2“);
  }
  }
  }
  });
  t1.start ();
  t2.start ();
  }
  }

线程一睡眠2秒之后锁定B同步打印1,但是这时候B已经被第二个线程锁定,并且第二天线程又锁定一个打印2,就这样一个等待B但是握着我不放,B等待一但是握着一个不放,就产生了死锁。

当然这段代码纯粹是为了演示死锁,在实际工作中基本上不会出现这种代码。在实际工作中线程可能拿到一个数据库锁,释放锁的时候抛出了异常,没释放掉。

一旦出现死锁,业务是可感知的,因为不能继续提供服务了,那么只能通过转储线程查看到底是哪个线程出现了问题,以下线程信息告诉我们是DeadLockDemo类的第42行和第31行引起的死锁。

“Thread-2"一家=5 tid=0=7 fc0458d1000国家免疫日[116 c1b000 x116c1c000等待监控条目   java.lang.Thread。状态:阻塞(对象监视器上)   在com.ifeve.book.forkjoin.DeadLockDemo 2.美元运行(DeadLockDemo.java: 42)   ——等待锁& lt; 7 fb2f3ec0>(以)   ——锁定& lt; 7 fb2f3ef8>(以)   java.lang.Thread.run (Thread.java: 695)   “Thread-1"一家=5 tid=0=7 fc0430f6800国家免疫日[116 b18000 x116b19000等待监控条目   java.lang.Thread。状态:阻塞(对象监视器上)   在1.美元com.ifeve.book.forkjoin.DeadLockDemo运行(DeadLockDemo.java: 31)   ——等待锁& lt; 7 fb2f3ef8>(以)   ——锁定& lt; 7 fb2f3ec0>(以)   java.lang.Thread.run (Thread.j

<强>避免死锁的方法

1,避免一个线程同时获取多个锁。

2,避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。

3,尝试使用定时锁,使用lock.tryLock(超时)来替代使用内部锁机制。

4,对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

<强>什么是资源限制

资源限制是指在进行并发编程时,程序的执行速度受限于计算机硬件资源或软件资源,例如,服务器的带宽只有2 mb/s,某个资源的下载速度是1 mb/s每秒,系统启动10个线程下载资源,下载速度不会变成10 mb/s,所以在进行并发编程时,要考虑这些资源的限制。硬件资源限制有带宽的上/下传载速度,硬盘读写速度和CPU的处理速度。软件资源限制有数据库的连接数和套接字连接数等。

Java实现多线程死锁与资源限制