细说多线程(八) —— 计时器与锁 |
发布时间: 2012/9/16 6:40:51 |
目录 八、定时器与锁 8.1定时器 若要长期定时进行一些工作,比如像邮箱更新,实时收听信息等等,可以利用定时器Timer进行操作。 开发实例 class Program { static void Main(string[] args) { ThreadPool.SetMaxThreads(1000, 1000); TimerCallback callback = new TimerCallback(ThreadPoolMessage); Timer t = new Timer(callback,"Hello Jack! ", 0, 1000); Console.ReadKey(); } //显示线程池现状 注意观察运行结果,每次调用Timer绑定的方法时不一定是使用同一线程,但线程都会是来自工作者线程的后台线程。
在使用多线程开发时,存在一定的共用数据,为了避免多线程同时操作同一数据,.NET提供了lock、Monitor、Interlocked等多个锁定数据的方式。 8.2.1 lock lock的使用比较简单,如果需要锁定某个对象时,可以直接使用lock(this)的方式。 1 private void Method() 2 { 3 lock(this) 4 { 5 //在此进行的操作能保证在同一时间内只有一个线程对此对象操作 如果操作只锁定某段代码,可以事先建立一个object对象,并对此对象进行操作锁定,这也是.net提倡的锁定用法。 class Control { private object obj=new object(); public void Method() { lock(obj) {.......} } }
8.2.2 Montior Montior存在于System.Thread命名空间内,相比lock,Montior使用更灵活。 1 class Control 2 { 3 private object obj=new object(); 4 5 public void Method() 6 { 7 Monitor.Enter(obj); 8 try 9 {......} 10 catch(Excetion ex) 11 {......} 12 finally 13 { 14 Monitor.Exit(obj); 15 } 16 } 17 } 18 使用try的方式,能确保程序不会因死锁而释放出异常!
8.2.3 Interlocked Interlocked存在于System.Thread命名空间内,它的操作比Monitor使用更简单。 Increment、Decrement 可以使参数安全地加1或减1并返回递增后的新值。 class Example { private int a=1; public void AddOne() { int newA=Interlocked.Increment(ref a); } } Exchange可以安全地变量赋值。 1 public void SetData() 2 { 3 Interlocked.Exchange(ref a,100); 4 } CompareExchange使用特别方便,它相当于if的用法,当a等于1时,则把100赋值给a。 public void CompareAndExchange() { Interlocked.CompareExchange(ref a,100,1); }
熟悉掌握多线程开发,对提高系统工作效率非常有帮助,尤其是回调方法与最近火热的并行编程更应该引起各位的重视。 本文出自:亿恩科技【www.enkj.com】 |