C#(五十五)之线程死锁

news2024/10/6 10:35:58

死锁是指多个线程共享资源是,都占用同意部分资源,而且都在等待对方师范另一部分资源,从而导致程序停滞不前的情况

示例:

/// <summary>
        /// 定义一个刀
        /// </summary>
        public static object knife = new object();
        /// <summary>
        /// 定义一把叉子
        /// </summary>
        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
    {
        /// <summary>
        /// 定义一个刀
        /// </summary>
        public static object knife = new object();
        /// <summary>
        /// 定义一把叉子
        /// </summary>
        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.coloradmin.cn/o/723600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git install报错问题

报错如下&#xff1a; fatal: unable to connect to githurb.com: 运行如下命令即可&#xff1a; git config --global url.https://github.com/.insteadOf git://github.com/ git config --global url."https://".insteadOf git://接着再删除node_moudels包&…

Spring Boot 操作 Redis 的各种实现

一、Jedis,Redisson,Lettuce三者的区别 共同点&#xff1a;都提供了基于Redis操作的Java API&#xff0c;只是封装程度&#xff0c;具体实现稍有不同。 不同点&#xff1a; 1.1、Jedis 是Redis的Java实现的客户端。支持基本的数据类型如&#xff1a;String、Hash、List、Se…

卡尔曼滤波实例分析(二)

1 问题 假设一物体以一初速度 v 0 v_0 v0​位于一高度为 y 0 y_0 y0​处正处于匀速下降状态&#xff0c;此时该物体启动制动装置&#xff0c;以一个加速度为 a a a的作用力反向运动 &#xff08;1&#xff09;建模 速度&#xff1a; V V 0 − a ∗ t V V_0 - a*t VV0​−a∗…

API6中JS UI实现富文本组件居右显示

【关键字】 RichText、富文本组件、API6、JS UI、居右显示 【关键代码如下】 index.hml <div class"container"><text>文本行高</text><text>文本行高</text><text>文本行高</text><text>文本行高</text>&…

SciencePub学术 | 计算机与生物信息类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 计算机与生物信息类重点SCIE&EI征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 计算机与生物信息类重点SCIE&EI 【期刊简介】IF&#xff1a;7.5-8.0&#xff0c;JCR1区&#xff0c;中科院1区TOP&…

vscode设置自己用的注释格式

ctrlshiftP 打开设置 输入snippets&#xff0c;选择配置用户代码片段[Snippets: Configure User Snippets]输入JavaScript&#xff0c;选择JavaScript.json 把这段代码替换进去 "Print to jsNoteTitle": {"prefix": "jsNoteTitle","body&q…

阿里云国际站:阿里云还值得我们期待吗?

阿里云还值得我们期待吗&#xff1f;   "阿里云&#xff0c;还可以继续期待吗&#xff1f;"这是一个近期在各大行业论坛和科技洪流之中频繁引发热议的问题。然而&#xff0c;深究其实质&#xff0c;答案不言自明——无须怀疑&#xff0c;阿里云绝对值得我们赋予期待…

MTK日志路径——aosp\device\mediatek\common\mtklog

这里写目录标题 device\mediatek\common\mtklog1.mtklog-config-basic-eng.prop2.mtklog-config-basic-user.prop3.mtklog-config-bsp-eng.prop4.mtklog-config-bsp-user.prop device\mediatek\common\mtklog 在安卓源码中&#xff0c;device\mediatek\common\mtklog目录包含了…

解决node+mysql不能保存emoji表情包的问题

效果图 1.前端 2.数据库 实现 Emoji表情是4个字节&#xff0c;而mysql的utf8编码最多3个字节&#xff0c;所以数据插不进去&#xff0c;而utfmb64是支持四个字节的。所以需要将mysql编码从utf8转换成utf8mb4&#xff0c;从【数据库、表、相应字段】都需要修改为utf8mb4&…

Flask+Vue+小程序电商生态系统

完整资料进入【数字空间】查看——baidu搜索"writebug" 本项目为FlaskVue小程序全栈开源电商生态系统。本项目使用的技术有&#xff1a;前端&#xff1a;VueIviewWxxcx&#xff1b;后端&#xff1a;FlaskMysql&#xff1b;部署&#xff1a;NginxGunicorn。该项目包含…

C++—异常与类型转换、大小端存储、不使用额外空间的情况下交换两个数

异常 常见的异常包括&#xff1a;数组下标越界&#xff0c;除法计算的时候除数为0&#xff0c;动态分配空间时空间不足。 try&#xff0c;throw&#xff0c;catch #include <iostream> using namespace std; int main() {double m 1, n 0;try {cout << "b…

其实,大多数的项目经理都是在假装努力罢了

早上好&#xff0c;我是老原。 有很多项目经理平时忙的团团转&#xff0c;看起来努力的不行&#xff0c;但实际上进度缓慢、结果不佳&#xff0c;更别说个人成长了&#xff0c;问就是工作都这么忙了&#xff0c;哪有时间。 说来也能理解&#xff0c;毕竟现在不是007就是996&a…

spring整合RabbitMQ

先导入依赖POM.xml 之前导的不全一直报错后面导入的可能有多的 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

Python3,66行代码,搞了个音乐下载器,从此听歌再也不需要花费银子了,真香!

66行代码敲出音乐下载器 1、引言2、代码实战2.1 思路2.2 安装2.3 示例 3、 总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;最近比较流行的那首歌&#xff0c; 咋又说费了。 小鱼&#xff1a;那你就冲个VIP呗。 小屌丝&#xff1a;开玩笑&#xff0c; 我的钱又不是大风刮过来…

第2集丨JavaScript 中原型链(prototype chain)与继承

目录 一、一些基础概念1.1 ECMAScript 标准1.2 prototype和 __proto__1.3 constructor属性1.4 函数名 二、原型链的维护2.1 内部原型链和构造器原型链2.2 从实例回溯原型链2.3 修正原型指向 三、基于原型链的继承3.1 继承属性3.2 继承“方法” 四、构造函数4.1 案例一个简单的实…

SAP S4 Hana 财务凭证存储表变化

一、统一日记账的表 1. ACDOCA里有的&#xff0c;BSEG里不一定有 以下的一些凭证行项目&#xff0c;都是只在ACDOCA表里面存在&#xff0c;而在BSEG表里不存在的&#xff08;你可以通过BKPF表的BSTAT字段的凭证状态U来识别&#xff09;&#xff1a; 资产折旧过账 特定账套&am…

VMware Workstation虚拟机如何连接usb网卡

小伙伴不知道怎么将网卡链接到VMware虚拟机系统里面&#xff0c;因此今天我们就做一个简单的教程&#xff0c;教大家如何连接虚拟机使用&#xff1a; 1.插上usb网卡&#xff0c;然后如下图所示操作&#xff1a; 2.点击连接网卡到虚拟机之后&#xff0c;查询一下网卡是否识别到…

【JAVA程序员学C++】第二节、引用与指针,类型转换,结构体

一、指针与引用 1.1 指针 先说指针&#xff0c;由于java有jvm&#xff0c;所以对于java程序员&#xff0c;对于内存这一块关注就毕竟少了。但是C不同&#xff0c;C里面所有的堆内存&#xff0c;都需要程序员自己把控&#xff0c;把控不好&#xff0c;泄露了也是常有的事情。 …

Leetcode刷题笔记--Hot11-20

1--有效的括号&#xff08;20&#xff09; 主要思路&#xff1a; 利用栈&#xff0c;遍历字符串&#xff0c;遇到左括号则入栈&#xff0c;遇到右括号则出栈&#xff0c;并判断出栈元素是否与右括号匹配&#xff1b; 当字符串有效时&#xff0c;栈为空&#xff08;所有左括号都…

python语法 数据结构-字典和集合

文章目录 1. 字典1. 1. 字典特征1. 2. 创建字典1. 3.字典常用方法1.3.1 get()1.3.2 clear()1.3.3 copy()1.3.4 copy()1.3.4 update(key value)1.3.5 keys()、 values()和items() 1. 4. 获取字典值1. 4.1 通过 Key1. 4.2 通过迭代 1. 5. 列表与运算符 2. 集合2. 1. 元组特征2. …