多线程死锁问题。
我们知道,多线程可以改善系统的资源利用率,并且可以提高程序的运行效率。但是,多线程也带来了新的问题,即:死锁问题。
1、死锁的概念
死锁可以理解为多个线程为了争夺同一个资源,而出现互相等待的一种现象。例如:线程A占有了记录1,正在等待记录2,而线程B占有了记录2,正在等待记录1,这样由于两个线程都在等待对方线程释放占有的记录,从而就导致了一个死循环,这就称为死锁。
2、死锁产生的条件
死锁产生需要满足下面4个基本的条件:
<1>互斥条件
即线程共享的资源必须是互斥的。同一时刻只能有一个线程占有共享资源。
<2>不剥夺条件
线程在获得的资源使用完毕之前,其他线程不能争夺该资源,必须有当前线程主动释放该资源。
<3>请求和保持条件
当前线程已经占有了一个资源,此时又有一个新的资源出现,并且新资源被其他线程占有,而当前线程如果去请求新资源时,则会处于阻塞状态,但不释放之前占有的资源。
<4>循环且等待条件
存在一组循环等待线程链,线程P1的资源被线程P2占有,线程P2的资源被线程P3占有,一直到线程Pn的资源被线程P1占有。
3、死锁的避免
解决死锁的技术,主要有以下三种:
<1>加锁顺序
按照顺序加锁是一种有效的死锁预防机制。
<2>加锁时限
当一个线程在尝试获取锁的过程中超过了这个时限则该线程应该放弃对该锁进行请求。
<3>死锁检测
每当一个线程获得了锁,会在线程和锁相关的数据结构中将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。
当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。
4、死锁的代码演示
<1>创建一个线程类
<2>创建一个专门用于存放锁对象的类
<3>在main方法中,创建两个线程并且运行
<4>运行结果
分析:如果不出现死锁现象,则正确的输入结果应该有4行字符串。从上图的运行结果中可以看出,由于线程t1中,执行的代码是先锁locka,在锁lockb,而线程t2是先锁lockb,在锁locka,两个线程都锁住了对方的资源,所以互相等待对方释放资源,从而出现死锁现象。
综上,Java中的多线程死锁问题介绍完了。