解析使用C# lock同时访问共享数据

经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。


代码如下:

public class AccessControl()
{
    private static object privateObjectLock = new object();
    public static AccessResult()
    {
       lock(privateObjectLock)
       {
         //数据操作语句
       }
    }
}

=====================================================
C#多线程中lock的用法
在做邮箱接收网关的时候遇到了以下的需求,要求为每一个邮箱开启一个接收线程,从POP3服务器上收取,然后将邮件存放到统一的FTP服务器上,要求邮件按收接顺充从1开始顺充编号。
我实现的方法为,为每个邮箱new出实例,然后分别赋给POP3邮箱地址,用户名,密码等参数。这里涉及到一个编号同步的问题,因为每个接收邮件的线程都是自己执行,所以取得编号并且递增这个动作是互斥的。
以一个静态变量表示编号如下


代码如下:

class EmailInfo
{
   public static int CurrentNumber;
}

那在当前线程取得这个步骤为


代码如下:

_CurrentNumber=++EmailInfo.CurrentNumber;

虽然此为一句,但在计算机运行时却分为多步,如下
EmialInfo.CurrentNumber加1--EmailInfo.CurrentNumber返回值给_CurrentNumber
,也许线程1执行了EmailInfo.CurrentNumber加1 的操作,但还没有取得返回值,此时线程2又执行了EmailInfo.CurrentNumber加1的操作,然后又线程1,线程2取得了返回值就是一样的,这样就失去了按顺序递增的作用。
此时查找了网上有关线程同步的方法,其实用lock语句锁住递增的那一段即可。而介绍的相关用法为


代码如下:

lock(this)
{
   _CurrentNumber=++EmailInfo.CurrentNumber;
}

本以为这样就可以成功,谁知道还是无效,反复查找才发现没弄清楚lock的用法。因为网上所讲的资料,举的例子比较简单,是直接new 出一个对像,然后为对像的一个函数创建了多个线程运行,所以它的同步只要lock住this即它自己就行了。因为此时只有一个实例在运,而我是new 出了多个对像,lock住每个自己的实例所以当然无效。

所以自然想了一个解决方法,就lock住相同的一个实例就行了。因为我每个邮件接收线程的参数都是不同的,所以还是new出几个实像,但lock的方法改为如下
先为EmailInfo加一个静态变量


代码如下:

class EmailInfo
{
   public static object syncRoot = new object();
   public static int CurrentNumber;
}

然后lock改为


代码如下:

lock(EmailInfo.syncRoot)
{
   _CurrentNumber=++EmailInfo.CurrentNumber;
}

即可实现想要的效果了。
写出来之后发现原来是件很简单的事,就是lock住一个大家都共同访问的(静态static的)东东就行了,但这个却搞了我很长时间。究其原因对所查资料没有认真理解,拿来就用,以为什么都懂,其实不然。
我想可能有初学者也会犯类似的错误,所以写出来以求共勉。欢迎学习C#或工作中用到C#的朋友与我交流

(0)

相关推荐

  • C#中lock死锁实例教程

    在c#中有个关键字lock,它的作用是锁定某一代码块,让同一时间只有一个线程访问该代码块,本文就来谈谈lock关键字的原理和其中应注意的几个问题: lock的使用原型是: lock(X) { //需要锁定的代码.... } 首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到了lock(X)而ABC因为此时都占有X,这时ABC就要停下

  • C#中Monitor对象与Lock关键字的区别分析

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit()).2.Monitor的常用属性和方法: Enter(Object) 在指定对象上获取排他锁. Exit(Object) 释放指定对象上的排他锁. IsEnter

  • C#中lock用法详解

    本文实例讲述了C#中lock的用法.分享给大家供大家参考.具体分析如下: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. 先来看看执行过程,代码示例如下: lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁. lock-statement:(lock 语句:) 复制代码 代码如下: lock(expression) embedded-statement(lock   (   表达式   )   嵌入语句

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

    线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程. 多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率. 多线程的应用程序域是相当不稳定的,因为多个线程在同一时间内都能运行共享的功能模块.为了保护应用程序的资源不被破坏,为多线程程序提供了三种加锁的机制,分别是:Monitor类.Lock关键字和Mutex类. 1. lock lock实现的功能是:使后进入的线程不会中断当前的线程,而是等待当前线程结束后再继续执行. 应用: 复制代码 代码如下:

  • 描述C#多线程中lock关键字的使用分析

    本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待.每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生.C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一

  • C#中实现线程同步lock关键字的用法详解

    1. lock关键字保证一个代码块在执行的过程中不会受到其他线程的干扰,这是通过在该代码块的运行过程中对特定的对象加互斥锁来实现的. 2. lock关键字的参数必须是引用类型的对象.lock对基本数据类型如int,long等无效,因为它所作用的类型必须是对象.如果传入long类型数据,势必被转换为Int64结构类型,则加锁的是全新的对象引用.如果需要对它们进行互斥访问限制,可以使用System.Threading.Interlocked类提供的方法,这个类是提供原子操作的. 3. lock(th

  • 如何使用C#读写锁ReaderWriterLockSlim

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读取的效率.而如果采用读写锁,则多个线程可以同时读取该对象,只有等到对象被写入锁占用的时候,才会阻塞. 简单的说,当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞

  • C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法

    本文实例讲述了C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法.分享给大家供大家参考,具体如下: 摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景.该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据. 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的

  • c#多线程中Lock()关键字的用法小结

    本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待. 每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生. 其中,lock是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的.它可以保证当一个线程在关键

  • 解析使用C# lock同时访问共享数据

    经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码. 复制代码 代码如下: public class AccessControl(){    private static object privateObjectLock = new object();    public static AccessResult()    {       lock(

  • JS解析后台返回的JSON格式数据实例

    ajax中若没有定义dataType : "json",需要eval("("+data+")")将后台传回的数据转化为JSON格式,否则不需要转换. 遍历json中的array方法: $.each jquery.each for (var i in array) { array[i]. } 以上这篇JS解析后台返回的JSON格式数据实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • python3用PyPDF2解析pdf文件,用正则匹配数据方式

    我就废话不多说了,大家还是看代码吧! import PyPDF2 import re pdf_file = open('xxx.pdf', mode='rb') read_pdf = PyPDF2.PdfFileReader(pdf_file) # 获取pdf文件的所有页数 number_of_pages = read_pdf.getNumPages() # print('total_page: ', number_of_pages) line_list = [] # 循环遍历每一页 for i

  • java如何利用poi解析doc和docx中的数据

    前言 这个功能是工作中遇到的一个需求,需要把上传的word中的内容解析出来,其中包含段落字符串解析,和表格中的数据解析出来,需要支持doc和docx格式的数据 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能. 方法如下: 1.增加maven中的包 <dependency> <

  • Java解析照片拿到GPS位置数据的详细步骤

    目录 1.前提条件 2.代码环境 Java代码逐步解析照片拿到GPS位置数据,附上步骤讲解,附上源代码和jar包依赖 1.前提条件 第一,检查你图片是否是高清原图:第二,检查你的图片是否来自IPhone设备;第三,检查你拍照片时,是否打开了GPS:三者缺一不可 2.代码环境 A:需要的Jar包: <dependency> <groupId>com.drewnoakes</groupId> <artifactId>metadata-extractor</

  • Java中documentHelper解析xml获取想要的数据

    目录 获取单节点数据 获取数组节点数据 webservice接口的入参和出参都是xml格式的数据,网上有很多方法,下面我将使用documentHelper工具来解析xml格式的数据,获取到自己想要的数据 获取单节点数据 假设我们接口调用成功,出参类似以下格式 <treatyroot> <returncode>0000</returncode> <message>接口调用成功</message> </treatyroot> 这是我们就可

  • Android解析服务器端发来的xml数据示例

    Android跟服务器交互数据,有时数据量大时,就需要以xml形式的交互数据.这里来实现服务器给Android客户端发送xml数据,Android客户端解析. 服务器端我使用dom4j第三方包来组织xml数据,大家可自行百度下载.而Android客户端则使用 XmlPullParser来解析xml数据. 服务器端代码: 复制代码 代码如下: package servlet; import java.io.IOException; import java.io.PrintWriter; impor

  • Ruby解析处理YAML和json格式数据

    Ruby处理YAML Ruby的标准库YAML基于Psych:https://ruby-doc.org/stdlib-2.6.2/libdoc/psych/rdoc/Psych.html require 'yaml' 之后,为大多数的基本数据类型都提供了 to_ yaml() 方法,用于将各数据类型的对象转换为yaml格式. 例如: require 'yaml' require 'set' p "hello world".to_yaml p 123.to_yaml p %w(perl

  • python解析中国天气网的天气数据

    使用方法:terminal中输入 复制代码 代码如下: python weather.py http://www.weather.com.cn/weather/101010100.shtml 北京6天的天气数据 json格式 复制代码 代码如下: #coding=utf-8  #weather.py  import urllib  import re  import simplejson  import sys if len(sys.argv) != 2:      print 'please

  • php实现的一个很好用HTML解析器类可用于采集数据

    复制代码 代码如下: <?php    $oldSetting = libxml_use_internal_errors( true );    libxml_clear_errors();   /**  *   * -+-----------------------------------  * |PHP5 Framework - 2011  * |Web Site: www.iblue.cc  * |E-mail: mejinke@gmail.com  * |Date: 2012-10-12

随机推荐