过多的锁定也会有麻烦。在死锁中,至少有两个线程被挂起,并等待对方解除锁定。由于两个线程都在等待对方,就出现了死锁,线程将无限等待下去。

为了说明死锁,下面实例化 StateObject 类型的两个对象,并把它们传递给SampleTask 类的构造函数。创建两个任务,其中一个任务运行 Deadlock1() 方法,另一个任务运行 Deadlock2() 方法:

var statel = new StateObject();
var state2 = new StateObject();
new Task(new SampleTask(statel, state2).Deadlock1).Start();
new Task(new SampleTask(statel, state2).Deadlock2).Start();

Deadlock1() 和 Deadlock2() 方法现在改变两个对象 s1和 s2 的状态,所以生成了两个锁。Deadlock1() 方法先锁定 sl,接着锁定 s2。Deadlock2() 方法先锁定 s2,再锁定 sl。现在,有可能Deadlock1() 方法中 sl 的锁定会被解除。接着,出现一次线程切换,Deadlock2() 方法开始运行,并锁定 s2。第二个线程现在等待sl 锁定的解除。因为它需要等待,所以线程调度器再次调度第一个线程,但第一个线程在等待 s2 锁定的解除。这两个线程现在都在等待,只要锁定块没有结束,就不会解除锁定。这是一个典型的死锁。

public class SampleTask
{public SampleTask(StateObject sl, StateObject s2){_sl = sl; _s2 = s2;}private StateObject _sl;private StateObject _s2; public void Deadlock1() {int i = 0;while (true) {lock (_s1) {lock (_s2){_s1.ChangeState(i); _s2.ChangeState(i++);Console.WriteLine($"still running, {i}");}}}}public void Deadlock2(){int i = 0;while (ture){lock (_s2) {lock (_s1){_s1.ChangeState(i); _s2.ChangeState(i++);Console.WriteLine($"still running, {i}");}}}}
}

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

死锁问题并不总是像这样那么明显。一个线程锁定了 s1,接着锁定 s2;另一个线程锁定了 s2,接着锁定 s1。在本例中只需要改变锁定顺序,这两个线程就会以相同的顺序进行锁定。但是,在较大的应用程序中,锁定可能隐藏在方法的深处。为了避免这个问题,可以在应用程序的体系架构中,从一开始就设计好锁定顺序,也可以为锁定定义超时时间。

 微信公众号 

Dotnet讲堂

C# 线程问题之死锁相关推荐

  1. 菜鸟学习笔记:Java提升篇8(线程2——线程的基本信息、线程安全、死锁、生产者消费者模式、任务调度)

    菜鸟学习笔记:Java提升篇8(线程2--线程的基本信息.线程安全.死锁.生产者消费者模式.任务调度) 线程的基本信息 线程同步 线程安全 死锁 生产者消费者模式 任务调度(了解) 线程的基本信息 J ...

  2. Java 线程同步与死锁 学习笔记

    Java 线程同步与死锁 学习笔记 Java 线程同步与死锁 学习笔记 1 多线程共享数据 2 线程同步 3 同步准则 4 线程死锁 1. 多线程共享数据 在多线程操作中,多个线程可能同时处理同一个资 ...

  3. java同步与死锁_Java多线程 - 线程同步与死锁

    一.线程同步 1)模拟多个用户同时从银行账户里面取钱 ● Account 类:银行账户类,里面有一些账户的基本信息,以及操作账户信息的方法 //模拟银行账户 classAccount {private ...

  4. 简单的说一说java线程中的死锁和嵌套管程锁死问题?

    为什么80%的码农都做不了架构师?>>>    死锁指的是两个线程都在等待另一个线程释放锁,比如:线程T1获取了锁L1然后在等待获取锁L2,线程T2获取了锁L2然后在等待获取锁L1, ...

  5. java多线程同步与死锁,廖雪峰Java11多线程编程-2线程同步-3死锁

    在多线程编程中,要执行synchronized块,必须首先获得指定对象的锁. 1.Java的线程锁是可重入的锁 public void add(int m){ synchronized (lock){ ...

  6. java线程同步的死锁_Java基础之线程5-线程同步死锁

    死锁:线程之间因条件相互竞争,导致线程都不能正常执行完,从而产生了死锁. 死锁的例子: public class TestDeadLock implements Runnable { public i ...

  7. java中线程死锁及避免_如何避免Java线程中的死锁?

    java中线程死锁及避免 如何避免Java中的死锁? 是Java面试中最受欢迎的问题之一,也是本季多线程的风格,主要是在高层提出,并带有很多后续问题. 尽管问题看起来很基础,但是一旦您开始深入研究,大 ...

  8. 如何避免Java线程中的死锁?

    如何避免Java死锁? 是Java面试中最受欢迎的问题之一,也是本季多线程的风格,主要是在高层提出,并带有很多后续问题. 尽管问题看起来很基础,但是一旦您开始深入研究,大多数Java开发人员就会陷入困 ...

  9. Java——线程锁,死锁,等待唤醒机制

    一.线程锁 线程安全问题 其实,线程安全问题都是由全局变量及静态变量引起的.若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线程同时执行写操作,一般 ...

最新文章

  1. 浏览器内核_测量时间:从Java到内核再到
  2. mysql+5.5.18+linux+下载,mysql5.7.18+linux安装二进制包与运行
  3. C#中的类02:构造对象
  4. ASP.NET的错误处理机制之二(实例log4net)
  5. oracle学习--循环语句
  6. 计算机网络是通过通信媒体 把各个独立,计算机网络试题选择题精华
  7. 2013二级java真题_2013年计算机二级JAVA第八套模拟试题及答案详解
  8. 【Java】浅谈Java的I/O体系
  9. Beats与Jenkins日志读取在Windows上的基本实现
  10. [Swift]LeetCode1044. 最长重复子串 | Longest Duplicate Substring
  11. 13 -3 jquery选择器和 jquery动画
  12. lucene的两种分页操作
  13. java实现求数组中元素第二大的元素
  14. mongoVue的使用
  15. 程序员常用英语单词汇总
  16. 使用powershell提权的一些技巧
  17. 移动端的vm vh是什么
  18. Unity 渲染教程(一):矩阵
  19. centos7下zeppelin安装配置
  20. 步步为营二 C语言基本概念 和 数据类型

热门文章

  1. SFB 项目经验-07-Skype for Business 话机 Polycom CX700
  2. artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
  3. wpa_supplicant 无线网络配置
  4. virtualenv模块使用
  5. Ubuntu防火墙:ufw
  6. php之简单使用数据库
  7. wp7开发官方教程和开发包
  8. 数据结构C#版笔记--堆栈(Stack)
  9. [Delphi]根据输入日期按年月周日输出日期段
  10. 南京铁道学院计算机应用,南京铁道职业技术学院交通运营管理专业怎么样