1 死锁
是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,
若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
2 死锁的发生必须具备以下四个必要条件
1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。
如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,
而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,
即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;
P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
3 死锁产生的原因
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,
否则就会因争夺有限的资源而陷入死锁。
其次,进程运行推进顺序与速度不同,也可能产生死锁。
4. 死锁的例子
常见情景之一: 同步的嵌套
package Thread_study;
class Mylock
{
public static Mylock lockA = new Mylock();
public static Mylock lockB = new Mylock();
}
class Test implements Runnable
{
boolean flag ;
Test(boolean flag)
{
this.flag = flag;
}
public void method()
{
if(flag)
{
while(true)
synchronized (Mylock.lockA)
{
System.out.println("if......lockA");
synchronized (Mylock.lockB)
{
System.out.println("if......lockB");
}
}
}
else
{
while (true)
synchronized (Mylock.lockB)
{
System.out.println("else.......lockB");
synchronized (Mylock.lockA)
{
System.out.println("else.......lockA");
}
}
}
}
public void run()
{
this.method();
}
}
public class DeadLockDemo4
{
public static void main(String[] args)
{
Test p1 = new Test(true);
// Test p2 = new Test(false);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p1);
t1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
p1.flag = false;
t2.start();
}
}
例2
public class SynFunLockDemo3 {
public static void main(String[] args)
{
TicketDemo p = new TicketDemo();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
t1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
p.flag = false;
t2.start();
}
}
class TicketDemo implements Runnable
{
private int num = 1000;
boolean flag = true;
Object obj = new Object();
//同步函数
public synchronized void sale() {
synchronized (obj)
{
if (num > 0) {
try {
Thread.sleep(10);//
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "...function sale..." + num--);
}
}
}
public void run() {
if(flag)
while (true)
{
synchronized (obj)
{
this.sale();
}
}
else
{
while(true)
{
this.sale();
}
}
}
}