死锁是指多个线程共享资源是,都占用同意部分资源,而且都在等待对方师范另一部分资源,从而导致程序停滞不前的情况
示例:
///
/// 定义一个刀
///
public static object knife = new object();
///
/// 定义一把叉子
///
public static object fock = new object();
static void Main(string[] args)
{
Thread threadgirl = new Thread(delegate() {
lock (knife)
{
Console.WriteLine("外边的风景好美");
getKnife();
lock (fock)
{
getFock();
eat();
Console.WriteLine("女孩放下了叉");
Monitor.Pulse(fock);
}
Console.WriteLine("女孩放下了刀
");
Monitor.Pulse(knife);
}
});
threadgirl.Name = "女孩";
Thread threadboy = new Thread(delegate()
{
lock (fock)
{
Console.WriteLine("你更美");
getFock();
lock (knife)
{
getKnife();
eat();
Console.WriteLine("男孩放下了叉");
Monitor.Pulse(knife);
}
Console.WriteLine("男孩放下了刀");
Monitor.Pulse(fock);
}
});
threadboy.Name = "男孩";
threadgirl.Start();
threadboy.Start();
Console.ReadLine();
}
public static void eat()
{
Console.WriteLine(Thread.CurrentThread.Name+"吃了一块牛排");
}
public static void getKnife()
{
Console.WriteLine(Thread.CurrentThread.Name+"拿起了刀子");
}
public static void getFock()
{
Console.WriteLine(Thread.CurrentThread.Name+"拿起了叉子");
}
输出结果:
外边的风景好美
女孩拿起了刀子
女孩拿起了叉子
女孩吃了一块牛排
女孩放下了叉
女孩放下了刀
你更美
男孩拿起了叉子
男孩拿起了刀子
男孩吃了一块牛排
男孩放下了叉
男孩放下了刀
这样输出是正常的,如何让其变成死锁呢?
在两次锁定之间让其暂停一会,如下 增加 thread.Sleep(100);
Thread threadgirl = new Thread(delegate() {
lock (knife)
{
Console.WriteLine("外边的风景好美");
getKnife();
Thread.Sleep(100);
lock (fock)
{
getFock();
eat();
Console.WriteLine("女孩放下了叉");
Monitor.Pulse(fock);
}
Console.WriteLine("女孩放下了刀
");
Monitor.Pulse(knife);
}
});
输出结果:
外边的风景好美
女孩拿起了刀子
你更美
男孩拿起了叉子
为什么会出现这样的结果呢?
仔细观察第一部分代码,会发现,男孩和女孩两次锁定的对象顺序不同,女孩第一次锁定是刀,第二次是叉子。男孩正好相反。
将锁定的对象顺序改为一致之后,死锁消失。
多线程避免死锁关键,锁定对象顺序要相同。
测试使用全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace dieLock
{
class Program
{
///
/// 定义一个刀
///
public static object knife = new object();
///
/// 定义一把叉子
///
public static object fock = new object();
static void Main(string[] args)
{
Thread threadgirl = new Thread(delegate() {
lock (knife)
{
Console.WriteLine("外边的风景好美");
getKnife();
Thread.Sleep(100);
lock (fock)
{
getFock();
eat();
Console.WriteLine("女孩放下了叉");
Monitor.Pulse(fock);
}
Console.WriteLine("女孩放下了刀
");
Monitor.Pulse(knife);
}
});
threadgirl.Name = "女孩";
Thread threadboy = new Thread(delegate()
{
lock (knife)
{
Console.WriteLine("你更美");
getFock();
lock (fock)
{
getKnife();
eat();
Console.WriteLine("男孩放下了叉");
Monitor.Pulse(fock);
}
Console.WriteLine("男孩放下了刀");
Monitor.Pulse(knife);
}
});
threadboy.Name = "男孩";
threadgirl.Start();
threadboy.Start();
Console.ReadLine();
}
public static void eat()
{
Console.WriteLine(Thread.CurrentThread.Name+"吃了一块牛排");
}
public static void getKnife()
{
Console.WriteLine(Thread.CurrentThread.Name+"拿起了刀子");
}
public static void getFock()
{
Console.WriteLine(Thread.CurrentThread.Name+"拿起了叉子");
}
}
}
有好的建议,请在下方输入你的评论。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
系列文章 Nomad 系列文章 概述 Nomad 的网络和 Docker 的也有很大不同, 和 K8s 的有很大不同. 另外, Nomad 不同版本(Nomad 1.3 版本前后)或是否集成 Consul 及 CNI 等不同组件也会导致网络模式各不相同. 本文…