您的位置:首页 > 其它

线程同步作业(一):Lock,monitor

2008-07-23 17:58 253 查看
开发的系统有这样一个功能:产生单据号码。我的做法是查看数据表中单据号码栏位当前值,在此基础上加1生成新的单据号码并存储。原本没有想太多,但是我们老大看了后,跟我说,如果有两个用户同时访问到这个单据号码,那么新产生的号码对于数据表来说是重复的,怎么办?

这就涉及一个多用户访问共享资源的问题。如果该资源是只读的,没有问题,但是如果每个用户都可以对其更新操作,就会出现数据同步的问题。说到这里,想起来,上学的时候学习数据库就学过的银行取款的问题,记得当时的解决方案是加锁,当然今天要解决这个问题依然是加锁。

如果究其原因,可以知道,实际上这里涉及的是一个线程同步的问题(多用户实际上对服务器来说就是多线程的访问),msdn中对线程同步的讲述和解决方案解释的很详细。系统中关于共享访问资源(数据)的代码为关键代码,如果要实现同步,必须在一个线程访问的时候,对这段代码加锁控制。等这个线程访问完毕,释放锁,允许第二个线程的访问,以此类推

方案有很多,今天先阐述经常用到的:monitor, lock关键字

测试代码:


using System;


using System.Collections.Generic;


using System.Text;


using System.Threading;




namespace Demo1






{


class safeThread






{


private static object obj=new object(); //注意:这里设置的对象,最好是private,protected,不能public,否则容易出现问题




static void Main()






{


Thread thread = new Thread(new ThreadStart(foo));


thread.Name = "my thread";


thread.Start();




Thread thread2 = new Thread(new ThreadStart(foo));


thread2.Name = "my thread 2";


thread2.Start();




Thread thread3 = new Thread(new ThreadStart(foo));


thread3.Name = "my thread 3";


thread3.Start();


}




private static void foo()






{




Monitor.Enter(obj);






{


Console.WriteLine(Thread.CurrentThread.Name);




Console.WriteLine("Thead executinged");


}




Monitor.Exit(obj); //测试的时候把此句注释掉,即可看到lock的效果


}


}


} 其中Moniter包含的部分及时运行时我们要加锁的部分,在这里代码实现对数据(资源)的访问和更新。Lock关键字的使用更加便捷


private static void foo()






{


lock(obj);






{


//关键代码区域


Console.WriteLine(Thread.CurrentThread.Name);




Console.WriteLine("Thead executinged");


}


} 实际上,上述两种方式时等价的(msdn的说法)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: