> 文章列表 > JavaWeb——死锁详解

JavaWeb——死锁详解

JavaWeb——死锁详解

目录

一、定义

二、死锁

1、成因

(1)、一个线程,一把锁(可重入锁没事,不可重入锁产生死锁)

(2)、两个线程,两把锁(可重入锁也会产生死锁)

(3)、N个线程,M把锁 (线程数量和锁数量越多,越容易死锁)

2、必要条件(缺一不可)

三、解决方案

1、破坏死锁的必要条件

2、避免死锁

(1)、银行家算法


一、定义

死锁是指在多线程中,两个或多个线程在运行过程中相互等待对方释放资源,导致他们无法继续执行而处于一种僵局,影响程序运行。

二、死锁

1、成因

(1)、一个线程,一把锁(可重入锁没事,不可重入锁产生死锁)

Object locker=new Object();synchronized(locker){synchronized(locker){}
}

如果一个线程对同一把锁,连续加了两次锁,并且该锁还是不可重入锁时,会产生死锁。

注:synchronized是可重入锁

(2)、两个线程,两把锁(可重入锁也会产生死锁)

Object locker1=new Object();
Object locker2=new Object();synchronized(locker1){synchronized(locker2){}
}synchronized(locker2){synchronized(locker1){}
}

线程A先获取锁1,再获取锁2;线程B先获取锁2,再获取锁1。此时两个线程互相阻塞,双方都无法获取对方持有的锁。

(3)、N个线程,M把锁 (线程数量和锁数量越多,越容易死锁)

哲学家就餐问题:

五个哲学家随机进行吃面条(拿起筷子)和思考人生(放下筷子)。如果没拿到筷子就会等待,等待的过程不会放下手中的筷子。

哲学家在吃面条,有5位哲学家和5根筷子,哲学家们同时拿筷子。他们每个人都优先拿左手边的筷子,因此每个人都只拿到了一根筷子,于是他们每个人既无法吃面也无法放下筷子,都吃不了面条,这就产生了一个死锁问题。

2、必要条件(缺一不可)

  • 互斥使用:当多个线程对同一把锁产生竞争时,线程A拿到该把锁后,其他线程就不能使用。
  • 不可抢占:线程A获取锁B,其他线程想要获取锁B,只能由线程A自己主动释放,是不能被其他线程强行占有的。
  • 请求和保持:当线程A获取锁B时,除非该线程主动释放锁B,否则线程A就一直占有锁B。
  • 循环等待:存在一个线程等待资源的循环链,如:线程A等待线程B释放锁,线程B等待线程A释放锁。A、B锁都无法正常释放,也都无法完成各自的线程,陷入了一个循环等待的状态。

注:条件1和条件2是锁的基本特性,无法改变。可以通过改变条件3和条件4来避免死锁

三、解决方案

1、破坏死锁的必要条件

  • 破坏请求和保持条件:一次性申请所有需要的资源,避免在占有部分资源时再次申请新的资源。
  • 破坏循环等待条件:按顺序申请资源或规定所有线程的访问顺序。例如:如果需要同时获取更多把锁,约定加锁顺序,先对小的编号加锁,后对大的编号加锁。

注:只要破坏四个条件中的一个就可以避免死锁 

2、避免死锁

(1)、银行家算法