使用C# lock同时访问共享数据
2009-05-18 20:15
211 查看
经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。
public class AccessControl()
{
private static object privateObjectLock = new object();
public static AccessResult()
{
lock(privateObjectLock)
{
//数据操作语句
}
}
}
提供给 lock 的对象只是用来唯一地标识由多个线程共享的资源通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。因此,最好锁定不会被暂留的私有或受保护成员。某些类提供专门用于锁定的成员。例如,Array 类型提供 SyncRoot。许多集合类型也提供 SyncRoot。
以一个静态变量表示编号如下
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;
}
即可实现想要的效果了。
文章来自学IT网:http://www.xueit.com/html/2009-02/21_712_00.html
相关文章推荐
- 使用C# lock同时访问共享数据
- 使用C# lock同时访问共享数据
- 使用C# lock同时访问共享数据
- 解析使用C# lock同时访问共享数据
- 使用C# lock同时访问共享数据
- C#使用Lock访问共享数据的问题
- 使用C#访问百度指数:分析请求/响应数据(1)
- 《Effective C#》读书笔记——条目1:使用属性而不是可访问的数据成员<C#语言习惯>
- Android深入探究笔记之十 -- 使用 ContentProvider 共享数据(二),访问与添加通讯录
- Android之 内容提供器(1)——使用内容提供器访问其它程序共享的数据
- java多线程-使用ReadWriteLock同步数据访问
- 使用 ContentProvider 共享数据 访问与添加通讯录
- 线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用,不过要注意的是线程间需要做好同步。
- 使用C#访问百度指数:模拟发送请求/得到响应数据(2)
- Android深入探究笔记之十 -- 使用 ContentProvider 共享数据(二),访问与添加通讯录
- C++多线程笔记:使用std::lock_guard实现对共享数据的保护
- 使用C#访问百度指数:处理响应数据(3)
- 使用OPENDATASOURCE访问远程机器上共享文件夹中的ACCESS、Excel数据库
- [C#学习笔记之多线程2]多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore .
- 提高C#编程水平的50个要点 1.总是用属性 (Property) 来代替可访问的数据成员 2.在 readonly 和 const 之间,优先使用 readonly 3.在 as 和 强制类型转换之