这章的内容是真的有意思

特别是代码。

先贴上代码:

class Program
{
static void Main(string[] args)
{
object lock1 = new object(); object lock2 = new object(); new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock(lock2)
{
Thread.Sleep(); Console.WriteLine("Monitor.TryEnter allow not to get stuck,returning false after a specified timer is elapsed"); if(Monitor.TryEnter(lock1,5))
{
Console.WriteLine("Acquired a protected resource succesfully"); }
else
{
Console.WriteLine("Timerout cquiring a resource"); }
} new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock (lock2)
{
Console.WriteLine("This will be deadlock");
Thread.Sleep();
lock (lock1)
{
Console.WriteLine("Acquired a protected resource succesfully");
} }
Console.ReadKey();
}
static void LockTooMuch(object Lock1,object Lock2)
{
lock(Lock1)
{
Thread.Sleep(1); lock (Lock2)
{ } }
}
}

说实话,这章代码,我一开始没看明白。真的。

有些时候真的就是难者不会会者不难。

咱慢慢来来说。

咱先从这一部分开始:

   static  void LockTooMuch(object Lock1,object  Lock2)
{
lock(Lock1)
{
Thread.Sleep(); lock (Lock2)
{ } }
}

这一部分的代码很好理解:

传入两个引用类型的object参数。

然后是代码主要部分先是

锁死lock1

然后再lock1里面锁死lock2.

这个部分的锁死的代码,也就意味着解锁的顺序,lock1等待lock2执行完毕才会解锁lock1.

本章说避免锁死。那么什么是锁死?

那么我们来原书的代码:

    new Thread(() => LockTooMuch(lock1, lock2)).Start();
lock (lock2)
{
Console.WriteLine("This will be deadlock");
Thread.Sleep();
lock (lock1)
{
Console.WriteLine("Acquired a protected resource succesfully");
}
}

这一部分的代码加上静态的LockTooMatch的方法运行就会锁死。

我们按照这个思路清理一下代码:

 static void Main(string[] args)
{
object lock1 = new object(); object lock2 = new object(); new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock (lock2)
{
Console.WriteLine("This will be deadlock");
Thread.Sleep();
lock (lock1)
{
Console.WriteLine("Acquired a protected resource succesfully");
} }
Console.ReadKey();
}
static void LockTooMuch(object Lock1,object Lock2)
{
lock(Lock1)
{
Thread.Sleep(); lock (Lock2)
{ } }
}

see

永远锁死

为什么只会执行到这里呢?

  Console.WriteLine("This will be deadlock");

一步一步的

首先程序新开线程运行LockTooMuch,然后再主线程锁LOCK2输出内容,线程等待1S之后再锁LOCK1 在输出语句。

             lock (lock2)
{
Console.WriteLine("This will be deadlock");
Thread.Sleep();
lock (lock1)
{
Console.WriteLine("Acquired a protected resource succesfully");
} }

按照我们之前说的东西,L2必须等待L1结束才会释放。

这是主线程的部分。

下面是方法的部分

 static  void LockTooMuch(object Lock1,object  Lock2)
{
lock(Lock1)
{
Thread.Sleep(); lock (Lock2)
{ } }
}

同样也是L1等待L2的结束才会是否。

主线程和新开线程是同时的。

也就是会有竞争。

那么执行的顺序是什么呢?

很简单

主线程新开线程

主线锁LOCK2

新开线程执行锁LOCK1

主线程输出

新开线程等待1s

主线程等待1s

新开线程锁LOCK2但是失败

主线程锁LOCK1但是失败

程序停止继续向下运行

为什么主线程,新线程锁LOCK为什么会失败呢?

新开线程锁lock2会失败是因为主线程在用lock2而且还没有用完。

主线程锁lock1会失败是应为新开线程做用lock1还么有用完。

所以会锁死。

ok 我们知道锁死的原因,下面我们通过Monitor.TryEnter来避免锁死。

Monitor.TryEnter是作用什么呢?

TryEnter有三个重载方法。

常用的是带有等待时间的。

作用就是在规定的时间去尝试解锁资源,或者获取资源。如果获取成功就返回true,不成功就返回false。这个代码总会返回结果。超时也会返回不过是false,也就说锁死了也会有办法来处理,不会尴尬的停在那里了

我们看看代码:

 new Thread(() => LockTooMuch(lock1, lock2)).Start();

            lock(lock2)
{
Thread.Sleep(); Console.WriteLine("Monitor.TryEnter allow not to get stuck,returning false after a specified timer is elapsed"); if(Monitor.TryEnter(lock1,5))
{
Console.WriteLine("Acquired a protected resource succesfully"); }
else
{
Console.WriteLine("Timerout cquiring a resource"); }
}

ok 清理下会锁死的代码,来运行代码

执行了else内的代码,说明尝试解锁lock1失败了,和上面那个会死锁的代码一样的结果,但是这个却可以继续持续其他代码,不会卡在死锁的部分。

我们来看看执行的过程【大家可以在VS中 使用断点,逐语句等方式来观察线程的运行顺序】

主线程新开线程

主线锁LOCK2

新开线程执行锁LOCK1

主线程等待1s

新开线程等待1s

主线程输出语句

新开线程锁LOCK2但是失败

主线程尝试解锁LOCK1,5s内。(成功返回true 失败返回fasle 超时返回false)但是失败

主线程输出else内容

程序结束

执行的顺序和死锁的顺序差不多,但是结果却不一样的因为Monitor.TryEnter避免的死锁的尴尬地步,程序多线程中出现死锁,使用monitor.tryenter会很好的避免死锁。

《C#多线程编程实战》1.11 Monitor.TryEnter()避免死锁的更多相关文章

  1. C#多线程编程实战(二)

    1.1 简介 为了防止一个应用程序控制CPU而导致其他应用程序和操作系统本身永远被挂起这一可能情况,操作系统不得不使用某种方式将物理计算分割为一些虚拟的进程,并给予每个执行程序一定量的计算能力.此外操 ...

  2. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  3. ASP.Net教程系列:多线程编程实战(一)

    Web开发中使用多线程可以增强用户体验,尤其是多用户.多任务.海量数据和资源紧张的情况下.所以我们的ASP.Net教程设立多线程编程实战专题.下面这些代码范例都是入门级的,希望对对大家学习ASP.Ne ...

  4. Java多线程编程实战读书笔记(一)

    多线程的基础概念本人在学习多线程的时候发现一本书——java多线程编程实战指南.整理了一下书中的概念制作成了思维导图的形式.按照书中的章节整理,并添加一些个人的理解.

  5. Java多线程编程实战指南(核心篇)读书笔记(四)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  6. Java多线程编程实战指南(核心篇)读书笔记(三)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  7. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  8. Java多线程编程实战指南(核心篇)读书笔记(一)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76422930冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  9. 《Java多线程编程实战指南(核心篇)》阅读笔记

    <Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...

随机推荐

  1. 张瀚荣:如何用UE4制作3D动作游戏

    转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...

  2. mongoDB的了解

    一.什么是mongoDB? 1.MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能. 2.MongoDB 旨在为WEB ...

  3. java成神之——注释修饰符

    注释修饰符 自定义注释 元注释 通过反射在runtime访问注释 内置注释 多注释实例 错误写法 使用容器改写 使用@Repeatable元注释 注释继承 使用反射获取注释 获取类的注释 获取方法的注 ...

  4. Centos6.6安装Python3.5笔录

    1.CentOS6.6 安装Python3.5 的依赖包 yum groupinstall "Development tools" yum install zlib-devel b ...

  5. thingsboard在windows下安装和使用

    在官网下载thingsboard和tb-gateway 需要安装java8 thingsboard服务安装 https://thingsboard.io/docs/user-guide/install ...

  6. puclic 页面公共CSS样式

    body, div, dl, dt, dd, ul, ol, li, pre, form, fieldset, blockquote, h1, h2, h3, h4, h5, h6,p{ paddin ...

  7. LeetCode题解 #2 Add Two Numbers

    题目大意:使用链表表示的两个整数,计算出其和,以同样的形式返回. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 ...

  8. Oracle11gR2--删除数据库

    1. 停止ORACLE数据库 [oracle@localhost oracle]$ ps -ef|grep smon oracle 72550 1 0 14:23 ? 00:00:00 ora_smo ...

  9. NPOI-WebForm_Excel导入与导出

    本文面对的是第一次 接触NPOI的童鞋 不必为了一些琐碎的事情搞的心情烦躁 废话不多说先上 Demo 的全家福 接下来直接上代码 public partial class _Default : Sys ...

  10. OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱

    //参照FreeImage官网给出的CTextrueManager写的加载函数 //官方给的例子是用opengl3.0以下的旧GL写的,没有使用glGenerateMipmap(GL_TEXTURE_ ...