C#多线程死锁介绍与案例代码
作者:農碼一生 发布时间:2022-08-01 06:40:05
标签:C#,多线程,死锁
一、死锁简介
在多道程序设计环境下,多个进程可能竞争一定数量的资源,。一个进程申请资源,如果资源不可用,那么进程进入等待状态。如果所申请的资源被其他等待进程占有,那么该等待的进程有可能无法改变状态,这种情况下称之为死锁。
二、死锁条件
死锁的四个条件:
1.非抢占:资源不能被抢占
2.互斥:至少有一个资源必须处在非共享模式,即一次只能有一个进程使用,如果另一进程申请该资源,那么申请进程必须延迟直到该资源释放为止。
3.占有并等待:一个进程必须占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有。
4.循环等待:有一组进程{P0,P1,…Pn},P0等待的资源被P1占有,P1等待的资源被P2占有,Pn-1等待的资源被Pn占有,Pn等待的资源被P0占有。
形成死锁必须要满足这四个条件。那么违背这几个条件中的任何一个就不会形成死锁,这种方式成为 死锁预防,而死锁避免是动态的检测分配资源的状态是否安全。
三、解决办法
1.我们可以通过对锁加时效性,或者死锁检测来处理。
2.Monitor.TryEnter()方法。虽然这种方法可以解决死锁问题,但是最好还是不要出现死锁这种情况。
死锁案例代码
如下代码实现创建两个线程t1和t2,分别起初分配占用lock1和ock2资源。当一个线程t1占用资源lock1时,再去请求另外一个资源lock2时,此时由于另外一个线程t2在正占用资源t2,请求失败,等待释放资源。同时t2又发出请求资源lock1,但是lock1又被t1占用,没有释放,也只能进行等待。此时两个线程只能等待一直等待对方释放资源,这就称之为死锁。
namespace Deadlock
{
class DL
{
int field1 = 0;
int field2 = 0;
private object lock1 = new int[1];
private object lock2 = new int[1];
public void First(int val)
{
lock (lock1)
{
Console.WriteLine("First: Acquired lock 1: "
+ Thread.CurrentThread.GetHashCode() + " Now Sleeping.");
//Try commenting Thread.Sleep()
Thread.Sleep(1000);//此时t2线程占用资源
Console.WriteLine("First: Acquired lock 1: "
+ Thread.CurrentThread.GetHashCode() + " Now wants lock2.");
//当请求锁lock2时,lock被t2线程占用,等待释放
lock (lock2)
{
Console.WriteLine("First: Acquired lock 2: "
+ Thread.CurrentThread.GetHashCode());
field1 = val;
field2 = val;
}
}
}
public void Second(int val)
{
lock (lock2)
{
Console.WriteLine("Second: Acquired lock 2: "
+ Thread.CurrentThread.GetHashCode());
//当请求锁lock1时,lock1被t1线程占用,等待释放
lock (lock1)
{
Console.WriteLine("Second: Acquired lock 1: "
+ Thread.CurrentThread.GetHashCode());
field1 = val;
field2 = val;
}
}
}
}
public class MainApp
{
DL d = new DL();
public static void Main()
{
MainApp m = new MainApp();
Thread t1 = new Thread(new ThreadStart(m.Run1));
t1.Start();
Thread t2 = new Thread(new ThreadStart(m.Run2));
t2.Start();
Console.ReadLine();
}
public void Run1()
{
this.d.First(10);
}
public void Run2()
{
this.d.Second(10);
}
}
}
来源:https://www.cnblogs.com/wml-it/p/14797156.html


猜你喜欢
- activity_list.xml文件代码如下:<?xml version="1.0" encoding=&quo
- 问题在项目过程中使用MyBatis-Puls的saveBatch一次性添加大量数据时很慢原因MyBatis-Puls的saveBatch默认
- 本文实例为大家分享了Unity shader实现高斯模糊效果的具体代码,供大家参考,具体内容如下正常图:高斯模糊效果图:shader代码:S
- 一、WebSocket简介WebSocket协议通过在客户端和服务端之间提供全双工通信来进行Web和服务器的交互功能。在WebSocket应
- 今天在工作中突然遇到这个问题,开始郁闷得不行,查阅了很多资料才解决。话不多少先上图①解决连接超时问题1:在Linux下输入命令ifconfi
- 一、函数式接口概念函数式接口在Java中是指:有且仅有一个抽象方法的接口。 当然接口中可以包含其他的方法(默认,静态,私有)函数式接口,即适
- 本文实例讲述了Android实现Service获取当前位置(GPS+基站)的方法。分享给大家供大家参考。具体如下:需求详情:1)、Servi
- 本文实例讲述了Java实现的zip工具类。分享给大家供大家参考,具体如下:实现把zip解压到指定路径,把文件夹压缩到zip,把文件列表压缩为
- 1、Hello, KotlinBugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验
- Long end,long num,File file,String charset4个参数说明end 相当于坐标 ,tail 向上的起点,
- 1.spring配置文件<bean id="configproperties"  
- 1.可能是缓存导致的。解决方法:清除缓存!2.全局编译可能项目依赖别的模块,别的模块修改未进行编译,这时须先对依赖模块进行编译补充知识:ID
- 本文实例讲述了Java数组的定义、初始化、及二维数组用法。分享给大家供大家参考,具体如下:数组的定义1.数组是有序数据的集合,数组中的每个元
- 本文实例为大家分享了Android自定义顶部标题栏展示的具体代码,供大家参考,具体内容如下思路及实现步骤1.定义标题栏布局2.自定义Titl
- 众所周知在android7.0,修改了对私有存储的限制,导致在获取资源的时候,不能通过Uri.fromFile来获取uri了我们需要适配7.
- 前言今天记录一个前段时间遇到的一个小问题的解决方法, 跨域!!!相信跨域这个问题, 做开发的或多或少都遇到过, 而且已经有很多博主已经分享了
- 这篇文章主要介绍了Java JDBC导致的反序列化攻击原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 第一个方法是计算出阶乘然后计算字符串的0的个数。import java.util.Scanner;import java.math.BigD
- 概述公司的spring boot项目不是使用默认的logback作为日志框架,而是log4j2, 主要原因是logback出现过一个生产问题
- 在 Android 的一些界面中,有时候我们需要为一副图片生成大小为 n * n 的缩略图,有时候需要的缩略图特殊一些,比如:1、带圆角的缩