死锁
死锁概念:如果一个进程在等待一个不可能发生的事,则进程就死锁了。而如果一个或多个进程产生死锁,就会造成系统死锁。
死锁发生的必要条件:
互斥条件:即一个资源每次只能被一个进程使用,在操作系统中这是真实存在的情况。
保持和等待条件:有一个进程已获得了一些资源,但因请求其他资源被阻塞时,对已获得的资源保持不放。
不剥夺条件:有些资源是不可剥夺的,当某个进程已获得这种资源后,系统不能强行收回,只能由进程使用完时自己释放。
环路等待条件:若干个进程形成环形链,每个都占用对方要申请的下一个资源。
解决死锁的策略:
死锁预防:例如:要求用户申请资源时一起申请所需的全部资源,这就破坏了保持和等待条件;将资源分层,得到上一层资源后,才能够申请下一层资源,它破坏了环路等待条件。预防通常会降低系统效率。
死锁避免:避免是指进程在每次申请资源时判断这些操作是否安全,典型算法是“银行家算法”。但这种算法会增加系统的开销。
死锁检测:前两者是事前措施,而死锁的检测则是判断系统是否处于死锁状态,如果是,则执行死锁解决策略。
死锁解除:这是与死锁检测结合使用的,它使用的方式就是剥夺。即将资源强行分配给别的进程。
死锁程序举例:
import java.lang.Exception;
public class TestDeadLock implements Runnable
{
public int flag=1;
static Object o1=new Object(),o2=new Object();
public void run()
{
if(flag==1)
{
synchronized(o1)
{
try
{
Thread.sleep(500);
}
catch(Exception e)
{
e.printStackTrace();
}
synchronized(o2)
{
System.out.println("1");
}
}
}
if(flag==0)
{
synchronized(o2)
{
try
{
Thread.sleep(500);
}
catch(Exception e)
{
e.printStackTrace();
}
synchronized(o1)
{
System.out.println("0");
}
}
}
}
public static void main(String[]args)
{
TestDeadLock tdl1=new TestDeadLock();
TestDeadLock tdl2=new TestDeadLock();
tdl1.flag=1;
tdl2.flag=0;
Thread t1=new Thread(tdl1);
Thread t2=new Thread(tdl2);
t1.start();
t2.start();
}
}
在这个程序中,线程t1抱住锁o1,等待锁o2;而线程t2则抱住锁o2,等待锁o1.就如那个著名的哲学家吃饭问题一样
*设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,
*但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿时才试图分两次从两边拿起筷子就餐。
*条件:
*1)拿到两只筷子时哲学家才开始吃饭。
*2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子。
*3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子。
这样,每个人都达不到吃饭的条件。