最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
C# lock 用法详解
时间:2022-06-25 08:29:01 编辑:袖梨 来源:一聚教程网
对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从c#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。
#include
#include
#includeint main(void)
{
clock_t start, end;
start = clock();delay(2000);
end = clock();
printf( "the time was: %fn ", (end - start) / clk_tck);return 0;
}
在做邮箱接收网关的时候遇到了以下的需求,要求为每一个邮箱开启一个接收线程,从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; }
c# lock同时访问共享数据
同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从c#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。
public class accesscontrol()
{
private static object privateobjectlock = new object();public static accessresult()
{
lock(privateobjectlock)
{
//数据操作语句
}
}
}
下面个lock用法实例
using system;
namespace threadtest29
{
class account
{
private object thislock = new object();
int balance;
random r = new random();public account(int initial)
{
balance = initial;
}int withdraw(int amount)
{
if (balance < 0)
{
throw new exception("负的balance.");
}
//确保只有一个线程使用资源,一个进入临界状态,使用对象互斥锁,10个启动了的线程不能全部执行该方法
lock (thislock)
{
if (balance >= amount)
{
console.writeline("----------------------------:" + system.threading.thread.currentthread.name + "---------------");
console.writeline("调用withdrawal之前的balance:" + balance);
console.writeline("把amount输入 withdrawal :-" + amount);
//如果没有加对象互斥锁,则可能10个线程都执行下面的减法,加减法所耗时间片段非常小,可能多个线程同时执行,出现负数。
balance = balance - amount;
console.writeline("调用withdrawal之后的balance :" + balance);
return amount;
}
else
{
//最终结果
return 0;
}
}
}
public void dotransactions()
{
for (int i = 0; i < 100; i++)
{
//生成balance的被减数amount的随机数
withdraw(r.next(1, 100));
}
}
}class test
{
static void main(string[] args)
{
//初始化10个线程
system.threading.thread[] threads = new system.threading.thread[10];
//把balance初始化设定为1000
account acc = new account(1000);
for (int i = 0; i < 10; i++)
{
system.threading.thread t = new system.threading.thread(new system.threading.threadstart(acc.dotransactions));
threads[i] = t;
threads[i].name = "thread" + i.tostring();
}
for (int i = 0; i < 10; i++)
{
threads[i].start();
}
console.readkey();
}
}
}
相关文章
- 云星穹铁道权益升级怎么玩 云崩铁权益升级活动介绍 12-03
- 以闪亮之名山中绘梦怎么玩 以闪亮之名滢然花梦套装活动介绍 12-03
- 以闪亮之名绿野梦歌礼包怎么样 以闪亮之名绿野梦歌拍照礼包介绍 12-03
- 光遇12.6有什么更新 光遇12月6日更新内容介绍 12-03
- 伍六七暗影交锋测试资格怎么获得 伍六七暗影交锋内测资格获取方法 12-03
- 无限暖暖晶莹诗集怎么样 12-03