C#中的lock、Monitor、Mutex学习笔记

 更新时间:2015年01月20日 10:51:07   投稿:junjie  
这篇文章主要介绍了C#中的lock、Monitor、Mutex学习笔记,本文讲解的都是线程同步的一些知识,需要的朋友可以参考下

线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程。

多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率。

多线程的应用程序域是相当不稳定的,因为多个线程在同一时间内都能运行共享的功能模块。为了保护应用程序的资源不被破坏,为多线程程序提供了三种加锁的机制,分别是:Monitor类、Lock关键字和Mutex类。

1. lock

lock实现的功能是:使后进入的线程不会中断当前的线程,而是等待当前线程结束后再继续执行。

应用:

复制代码 代码如下:

   private Object thisLock=new object();

   lock(thisLock){
               //锁定的代码块
    }

注意:避免锁定 public 类型,否则实例将超出代码的控制范围。

常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock")
违反此准则:如果实例可以被公共访问,将出现 lock (this) 问题。
如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
下面举例说明lock的应用:
下面的例子中创建了5个次线程,次线程完成的任务就是:输出线程编码,延迟1秒,然后输出当时的时间

Example:

复制代码 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication5 {
    class Program {
        static void Main(string[] args) {
        Console.WriteLine ("程序开始时间:"+DateTime.Now .ToString());
        Example ex=new Example ();
        Thread []threads=new  Thread[5];
        for (int i=0;i<5;i++)
        {
        threads[i]=new Thread (new ThreadStart(ex.OutPut));
        threads[i].Name =string.Format ("Worker thread#{0}",i) ;
        }
        foreach(Thread t in threads){
        t.Start();
        }
        Console.WriteLine("主线程最后一句代码!"+DateTime.Now.ToString());
        }
    }
    class Example{
    private static object  thisLock=new object ();
    public void OutPut()
    {   
    lock(thisLock){
    Console .WriteLine("->{0}",Thread.CurrentThread.Name);
    Thread.Sleep(1000);
    Console.WriteLine(DateTime.Now);
    }
    }
   
    }
}

实验结果如下:

           图1:加lock

      图2:没有lock    

从实验结果可以看出,加lock后,程序每次只能执行一个线程,只有当前线程执行完了,才会执行下一个线程未加lock,程序执行混乱,容易阻塞。

2. Monitor

lock是对Monitor的Enter和Exit的一个封装,因此Monitor类的Enter()和Exit()方法的组合使用可以用lock关键字替代。

Monitor类除了具有lock的功能外,还有以下功能:

TryEnter()解决长期死等的问题,如果一个并发经常发生,并且持续时间很长,使用TryEnter,可以有效防止死锁或者长时间 的等待。    

Wait()释放对象上的锁,以便允许其他线程锁定和访问该对象。在其他线程访问对象时,调用线程将等待。脉冲信号用于通知等待线程有关对象状态的更改。

Pulse(),PulseAll()向一个或多个等待线程发送信号。该信号通知等待线程锁定对象的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以检查对象的新状态以查看是否达到所需状态。

注意:Pulse、PulseAll和Wait方法必须从同步的代码块内调用。

3. Mutex(互斥体)

Mutex的突出特点是可以跨应用程序域边界对资源进行独占访问,即可以用于同步不同进程中的线程,这种功能是以牺牲更多的系统资源为代价的。    

互斥体Mutex和事件对象EventWaitHandler属于内核对象,利用内核对象进行线程同步,线程必须要在用户模式和内核模式间切换,所以一般效率很低,但利用互斥对象和事件对象这样的内核对象,可以在多个进程中的各个线程间进行同步。

互斥体Mutex类似于一个接力棒,拿到接力棒的线程才可以开始跑,当然接力棒一次只属于一个线程(Thread Affinity),如果这个线程不释放接力棒(Mutex.ReleaseMutex),那么其他所有需要接力棒运行的线程只能等着看热闹。

相关文章

  • C# 网域账号(Domain)验证的实现

    C# 网域账号(Domain)验证的实现

    本文主要介绍了C# 网域账号(Domain)验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • C#使用 NAudio 实现音频可视化的方法

    C#使用 NAudio 实现音频可视化的方法

    这篇文章主要介绍了[C#] 使用 NAudio 实现音频可视化的相关资料,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • Unity实现粒子光效导出成png序列帧

    Unity实现粒子光效导出成png序列帧

    这篇文章主要为大家详细介绍了Unity实现粒子光效导出成png序列帧,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • 一篇文章带你轻松了解C# Lock关键字

    一篇文章带你轻松了解C# Lock关键字

    这篇文章主要给大家介绍了如何通过一篇文章带你轻松了解C# Lock关键字的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-06-06
  • c#防止多次运行代码收集分享

    c#防止多次运行代码收集分享

    原文:经过我的测试,还比较好用,但是有个问题,如果不注销,用另一个用户进入,则程序不能判断出已运行。所以只限于用在单用户环境,还是不太完美
    2013-09-09
  • 谈谈C# replace在正则表达式中的意义

    谈谈C# replace在正则表达式中的意义

    这篇文章主要介绍了C# replace在正则表达式中的意义的相关资料,需要的朋友可以参考下
    2016-03-03
  • C#(.net)中按字节数截取字符串最后出现乱码问题的解决

    C#(.net)中按字节数截取字符串最后出现乱码问题的解决

    这篇文章主要给大家介绍了关于C#(.net)中按字节数截取字符串最后出现乱码问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-06-06
  • C#之WinForm WebBrowser实用技巧汇总

    C#之WinForm WebBrowser实用技巧汇总

    这篇文章主要介绍了C#之WinForm WebBrowser实用技巧汇总,包括常见的各种设置及信息获取等,需要的朋友可以参考下
    2014-08-08
  • c#入门之枚举和结构体使用详解(控制台接收字符串以相反的方向输出)

    c#入门之枚举和结构体使用详解(控制台接收字符串以相反的方向输出)

    这篇文章主要介绍了c#入门之枚举和结构体使用详解,最后提供了编写控制台应用程序接收字符串并做相应处理的小示例,需要的朋友可以参考下
    2014-04-04
  • Unity Shader实现水波纹效果

    Unity Shader实现水波纹效果

    这篇文章主要为大家详细介绍了Unity Shader实现水波纹效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论