C#__资源访问冲突和死锁问题

news2025/1/20 21:57:22

    /// 线程的资源访问冲突:多个线程同时申请一个资源,造成读写错乱。
    /// 解决方案:上锁,lock{执行的程序段}:同一时刻,只允许一个线程访问该程序段。
    /// 死锁问题:
    /// 程序中的锁过多,某一线程需要多个锁资源,而某个资源被另一线程占用,另一个线程同样如此,(谁也不愿先释放资源)形成闭环,线程无法继续进行。
    /// 解决方案:使用调度算法,让某一个被占用的资源被线程释放或关闭某个线程。 

// 资源访问冲突

    class State
    {
        private Object _lock = new Object();
        private int state = 100;
        private void test()
        {
            if(100 == state)
            {
                Console.Write("state=" + state);
            }
            state++;
        }
        private void test2()
        {
            if (101 == state)
            {
                Console.Write("state=" + state);
            }
            state++;
        }

        public void ChangeState()
        {
            Thread h = new Thread(test);
            Thread v = new Thread(test2);

            // h.Start();
            // v.Start();
            // state=100state=100state=101state=100请按任意键继续. . .

            lock (_lock)
            {
                h.Start();
                v.Start();
                // state=100请按任意键继续. . .
                // state=100state=101请按任意键继续. . .
            }
        }
    }

// 主程序

    class StateProgram
    {
        static void Main(string[] args)
        {
            State state = new State();

            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(state.ChangeState);
                t.Start();
            }
            Thread.Sleep(1000);
        }
    }

// 死锁

    class Deadlock
    {
        Object _lock = new Object();
        Object _lock2 = new Object();

        private int flag = 0;

        public void test()
        {
            lock (_lock)
            {
                Console.WriteLine("我拿到了锁1");
                lock (_lock2)
                {
                    Console.WriteLine("我拿到了锁2");
                    if(0 == flag)
                    {
                        Console.WriteLine("我是第一名");
                        flag = 1;
                    }
                    else
                    {
                        Console.WriteLine("我是第二名");
                    }
                }
            }
        }

        public void test2()
        {
            lock (_lock2)
            {
                Console.WriteLine("他拿到了锁2");
                lock (_lock)
                {
                    Console.WriteLine("他拿到了锁1");
                    if (0 == flag)
                    {
                        Console.WriteLine("他是第一名");
                        flag = 1;
                    }
                    else
                    {
                        Console.WriteLine("他是第二名");
                    }
                }
            }
        }
    }

// 主程序

            Deadlock star = new Deadlock();

            Thread t1 = new Thread(star.test);
            Thread t2 = new Thread(star.test2);

            t1.Start();
            t2.Start();
            //我拿到了锁1
            //他拿到了锁2

// 解决方案1:锁同步

    class Deadlock
    {
        Object _lock = new Object();
        Object _lock2 = new Object();

        private int flag = 0;

        public void test()
        {
            lock (_lock)
            {
                Console.WriteLine("我拿到了锁1");
                lock (_lock2)
                {
                    Console.WriteLine("我拿到了锁2");
                    if(0 == flag)
                    {
                        Console.WriteLine("我是第一名");
                        flag = 1;
                    }
                    else
                    {
                        Console.WriteLine("我是第二名");
                    }
                }
            }
        }

        public void test2()
        {
            lock (_lock)
            {
                Console.WriteLine("他拿到了锁2");
                lock (_lock2)
                {
                    Console.WriteLine("他拿到了锁1");
                    if (0 == flag)
                    {
                        Console.WriteLine("他是第一名");
                        flag = 1;
                    }
                    else
                    {
                        Console.WriteLine("他是第二名");
                    }
                }
            }
        }
    }

我拿到了锁1
我拿到了锁2
我是第一名
他拿到了锁2
他拿到了锁1
他是第二名
请按任意键继续. . . 

// 解决方案2:做标签

    class Deadlock
    {
        Object _lock = new Object();
        Object _lock2 = new Object();

        private int flag = 0;
        private int _flag = 0;

        public void test()
        {
            if (0 == _flag)
            {
                lock (_lock)
                {
                    Console.WriteLine("我拿到了锁1");
                    lock (_lock2)
                    {
                        Console.WriteLine("我拿到了锁2");
                        if (0 == flag)
                        {
                            Console.WriteLine("我是第一名");
                            flag = 1;
                        }
                        else
                        {
                            Console.WriteLine("我是第二名");
                        }
                    }
                }
            }
            _flag = 1;
        }

        public void test2()
        {
            if(1 == _flag)
            {
                lock (_lock2)
                {
                    Console.WriteLine("他拿到了锁2");
                    lock (_lock)
                    {
                        Console.WriteLine("他拿到了锁1");
                        if (0 == flag)
                        {
                            Console.WriteLine("他是第一名");
                            flag = 1;
                        }
                        else
                        {
                            Console.WriteLine("他是第二名");
                        }
                    }
                }
            }

        }
    }
            Deadlock star = new Deadlock();
            Thread t1 = new Thread(star.test);
            Thread t2 = new Thread(star.test2);

            t1.Start();
            Thread.Sleep(1000);
            t2.Start();

我拿到了锁1
我拿到了锁2
我是第一名
他拿到了锁2
他拿到了锁1
他是第二名
请按任意键继续. . .

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/991346.html

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

相关文章

【数据结构】二叉树的顺序结构-堆

【数据结构】二叉树的顺序结构-堆 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储&#xff0c;需要注意的是这里的堆和操作系统虚拟进程地址空间…

Direct LiDAR-Inertial Odometry

DLIO Runing 运行效果&#xff1a; <video id“video” controls""src“data/dlio_ss.mp4” height“500” preload“none”> 论文 摘要 难点&#xff1a;快速运动 or 穿越不规则地形时降低精度&#xff0c;通常过于简单的方法而过高的计算量。本方案提出…

go-zero直连与etcd服务注册中心

go-zero中直连方式 在使用grpc是最重要的就是pb文件了&#xff0c;生成的pb文件&#xff0c;通过pb文件可以生成grpc的客户端和服务端&#xff0c;那么客户端和服务端就可以直连了&#xff0c;再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写&#xff0c;包…

如何面对未来的迷茫和热爱?

很多人并没有明确的热爱的事&#xff0c;就是按照一般规划安安稳稳地上学工作&#xff0c;并在一个不那么爱也不怎么讨厌的工作岗位上度过大部分人生。 首先&#xff0c;我必须说&#xff0c;我并不认为这有什么不妥。或许大部分人并不热爱自己的工作&#xff0c;但他们对自己的…

全球市场争夺战:如何提升品牌在海外市场的竞争力?

随着全球化的不断发展&#xff0c;越来越多的企业将目光投向了海外市场&#xff0c;希望能够在国际舞台上获得更大的发展机会。然而&#xff0c;海外市场的竞争激烈&#xff0c;如何有效地提升品牌在海外市场的竞争力成为了一个关键的问题。本文Nox聚星将和大家从多个方面探讨&…

CAR-NK治疗的商业化之旅

自然杀伤细胞NK细胞是一种重要的免疫效应细胞&#xff0c;能识别并杀伤病毒感染细胞和肿瘤细胞&#xff0c;不过NK细胞本身难以准确识别肿瘤细胞。科学家通过基因工程修饰&#xff0c;在NK细胞表面表达能够和肿瘤特定抗原结合的嵌合抗原受体CAR。跨膜结构域将CAR结构锚定在NK细…

DNS、ICMP协议和NAT技术

文章目录 1. DNS1.1 域名简介 2. NAT技术2.1 NAPT2.2 NAT技术的缺陷2.3 NAT和代理服务器 3. ICMP协议3.1 ping命令 4. 总结 1. DNS TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序&#xff0c;但是IP地址不方便记忆&#xff0c;于是人们发明了一种叫主机名的东西…

视频监控汇聚平台EasyNVR安防视频平台新版本无法对接到EasyNVS平台并报错login error,该如何解决?

安防监控系统EasyNVR视频云存储平台可实现设备接入、实时直播、录像、检索与回放、视频云存储、视频分发等视频能力服务&#xff0c;可覆盖全终端平台&#xff08;pc、手机、平板等终端&#xff09;&#xff0c;在智慧工厂、智慧工地、智慧社区、智慧校园等场景中有大量落地应用…

leetcode 671. 二叉树中第二小的节点(java)

二叉树中第二小的节点 题目描述DFS 深度优先遍历代码演示 题目描述 难度 - 简单 leetcode 671. 二叉树中第二小的节点 给定一个非空特殊的二叉树&#xff0c;每个节点都是正数&#xff0c;并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话&#xff0c;那么…

SpringMVC增删改查(CRUD)的实现

目录 前言 一、前期准备 1.pom.xml---依赖与插件的导入 2.jdbc.properties---数据库连接 3.log4j2.xml---日志文件 4.spring-mybatis 5.spring-context 6.spring-mvc 二、增删改查的实现 1.model与mapper层的生成 2.biz层 3.工具类 4.controller层 三、测试结果 总…

MySQL——select语句的简单介绍和查询时常用的参数

select语句详解 基本的select语句 select 要查询的列名 from 要查询的表 where 限制条件; 如果要查询表的所有内容&#xff0c;则把要查询的列名用—个星号*号表示(之间的案例中都已经使用过)&#xff0c;代表要查询表中所有的列。 而大多数情况&#xff0c;我们只需要查看…

Linux——(第七章)文件权限管理

目录 一、基本介绍 二、文件/目录的所有者 1.查看文件的所有者 2.修改文件所有者 三、文件/目录的所在组 1.修改文件/目录所在组 2.修改用户所在组 四、权限的基本介绍 五、rwx权限详解 1.rwx作用到文件 2.rwx作用到目录 六、修改权限 一、基本介绍 在Linux中&…

[docker]笔记-portainer的使用

1、安装完成后输入ip加端口号打开网页&#xff0c;并再相应位置输入初始密码&#xff0c;初始密码自行设置。 2、进入主页后可以看到如下图标&#xff1a; 3、选择docker环境&#xff0c;即可展示目前docker信息 可以看到目前有1个容器&#xff0c;3个卷和4个镜像&#xff0c…

【C++ • STL】一文带你走进string

文章目录 一、STL简介二、标准库中的string类三、string类的常用接口说明2.1 string类对象的常见构造2.2 string类对象的访问及遍历操作2.2.1 元素访问2.2.2 迭代器 2.3 string类对象的容量操作2.4 string类对象的修改操作2.5 string类非成员函数 四、总结 ヾ(๑╹◡╹)&#x…

西门子PLC如何与多个三菱PLC建立无线通信?

对一个大型工厂&#xff0c;由于生产线的不断改造、新老流程的不断更新&#xff0c;这些PLC系统往往是由不同的制造商提供的。那么在智慧工厂的实现中&#xff0c;常会遇到不同品牌PLC之间需要进行相互通讯的情况。由于场地和生产能效的原因&#xff0c;在后期的系统改造中&…

docker从零部署jenkins保姆级教程(上)

jenkins&#xff0c;基本是最常用的持续集成工具。在实际的工作中&#xff0c;后端研发一般没有jenkins的操作权限&#xff0c;只有一些查看权限&#xff0c;但是我们的代码是经过这个工具构建出来部署到服务器的&#xff0c;所以我觉着有必要了解一下这个工具的搭建过程以及简…

【Java 基础篇】Java 异常处理指南:解密异常处理的关键技巧

异常是 Java 编程中不可避免的一部分。无论你是刚刚入门 Java 编程&#xff0c;还是已经有一定经验&#xff0c;了解异常处理都是非常重要的。本篇博客将向你介绍 Java 中异常的基础知识&#xff0c;帮助你理解什么是异常、为什么需要异常处理以及如何在代码中处理异常。 什么…

最新SQL注入漏洞原理及与MySQL相关的知识点

点击星标&#xff0c;即时接收最新推文 本文选自《web安全攻防渗透测试实战指南&#xff08;第2版&#xff09;》 点击图片五折购书 SQL注入漏洞简介 SQL注入是指Web应用程序对用户输入数据的合法性没有判断&#xff0c;前端传入后端的参数是攻击者可控的&#xff0c;并且参数被…

Spring MVC:视图与视图解析器

Spring MVC 前言视图视图解析器附 前言 在上一章中&#xff0c;模型数据通过域对象共享的方式返回给前端控制器 DispatcherServlet 。那么&#xff0c;把结果封装成模型视图 ModelAndView 对象返回给前端控制器 DispatcherServlet 后&#xff0c;下一步是前端控制器 Dispatche…

二分搜索树节点的查找(Java 实例代码)

目录 二分搜索树节点的查找 Java 实例代码 src/runoob/binary/BinarySearchTreeSearch.java 文件代码&#xff1a; 二分搜索树节点的查找 二分搜索树没有下标, 所以针对二分搜索树的查找操作, 这里定义一个 contain 方法, 判断二分搜索树是否包含某个元素, 返回一个布尔型变…