线程学习6——死锁

死锁

多线程中,常见的一种问题除了竞态条件外就是死锁。

那什么是死锁呢?死锁就是:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

那么为什么会产生死锁呢?

1.因为系统资源不足。

2.进程运行推进的顺序不合适。

3.资源分配不当。

学过操作系统的朋友都知道:产生死锁的条件有四个:

1.互斥条件:所谓互斥就是进程在某一时间内独占资源。

2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。

4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁演示:

为了演示死锁,在类MyThread中,实例化了两个对象,obj1,obj2,并写了两个方法:

DeadLock1先是锁定了obj1,接着锁定obj2;DeadLock2先是锁定了obj2,再锁定了obj1。

现在有可能的方法DeadLock1中的obj1的锁定会被解除。接着出现一次线程切换,DeadLock2()开始运行,并锁定obj2。

第二个线程现在等待obj1锁定的解除。因为他需要等待,所以线程调度器在此调度第一个线程,但第一个线程在等待obj2锁定的解除。

这两个线程现在都在等待,只要锁定块没有结束,就不会解除锁定。这是一个典型的死锁。

MyThread:

using System.Threading;

namespace ConsoleApplication1
{
public class MyThread
{
private Object obj1 = new object();
private Object obj2 = new object();

public void DeadLock1()
{
while (true)
{
lock (obj1)
{
lock (obj2)
{
Console.WriteLine(
"我已经锁定obj2!");
}
}
}
}

public void DeadLock2()
{
while (true)
{
lock (obj2)
{
lock (obj1)
{
Console.WriteLine(
"我已经锁定obj1!");
}
}
}
}
}
}

入口程序Main:

static void Main(string[] args)
{
MyThread myThread
= new MyThread();
Thread thread1
= new Thread(myThread.DeadLock1);
Thread thread2
= new Thread(myThread.DeadLock2);
thread1.Start();
thread2.Start();
}

结果是:程序运行了许多循环,不久就没有响应了。数据在控制台写入几次。死锁问题的发生频率也取决于系统配置,每次运行的结果都不同。

如何避免:

可以在应用程序的体系架构中,从一开始就设计好锁定顺序,也可以为锁定定义超时时间。

posted @ 2011-06-01 15:29  佳园  阅读(454)  评论(0编辑  收藏  举报