博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
细说多线程(八) —— 计时器与锁
阅读量:6894 次
发布时间:2019-06-27

本文共 3189 字,大约阅读时间需要 10 分钟。

目录

 

八、定时器与锁

8.1定时器

若要长期定时进行一些工作,比如像邮箱更新,实时收听信息等等,可以利用定时器Timer进行操作。

在System.Threading命名空间中存在Timer类与对应的TimerCallback委托,它可以在后台线程中执行一些长期的定时操作,使主线程不受干扰。
Timer类中最常用的构造函数为 public Timer( timerCallback , object , int , int )
timerCallback委托可以绑定执行方法,执行方法必须返回void,它可以是无参数方法,也可以带一个object参数的方法。
第二个参数是为 timerCallback 委托输入的参数对象。
第三个参数是开始执行前等待的时间。
第四个参数是每次执行之间的等待时间。

开发实例

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();         }          //显示线程池现状          static void ThreadPoolMessage(object data)         {             int a, b;             ThreadPool.GetAvailableThreads(out a, out b);             string message = string.Format("{0}\n   CurrentThreadId is:{1}\n" +                 "   CurrentThread IsBackground:{2}\n" +                 "   WorkerThreads is:{3}\n   CompletionPortThreads is:{4}\n",                  data + "Time now is " + DateTime.Now.ToLongTimeString(),                  Thread.CurrentThread.ManagedThreadId,                  Thread.CurrentThread.IsBackground.ToString(),                  a.ToString(), b.ToString());             Console.WriteLine(message);         }     }

注意观察运行结果,每次调用Timer绑定的方法时不一定是使用同一线程,但线程都会是来自工作者线程的后台线程。

8.2 锁

在使用多线程开发时,存在一定的共用数据,为了避免多线程同时操作同一数据,.NET提供了lock、Monitor、Interlocked等多个锁定数据的方式。

8.2.1 lock

lock的使用比较简单,如果需要锁定某个对象时,可以直接使用lock(this)的方式。

1 private void Method()2 {3       lock(this)4       {5           //在此进行的操作能保证在同一时间内只有一个线程对此对象操作 6       }7 }

如果操作只锁定某段代码,可以事先建立一个object对象,并对此对象进行操作锁定,这也是.net提倡的锁定用法。

class Control {       private object obj=new object();              public void Method()       {             lock(obj)             {.......}       } }

 

8.2.2 Montior

Montior存在于System.Thread命名空间内,相比lock,Montior使用更灵活。

它存在 Enter, Exit 两个方法,它可以对对象进行锁定与解锁,比lock使用更灵活。

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             finally13             {14                 Monitor.Exit(obj);15             }16       }17 }18

使用try的方式,能确保程序不会因死锁而释放出异常!

而且在finally中释放obj对象能够确保无论是否出现死锁状态,系统都会释放obj对象。
而且Monitor中还存在Wait方法可以让线程等待一段时间,然后在完成时使用Pulse、PulseAll等方法通知等待线程。

 

8.2.3 Interlocked

Interlocked存在于System.Thread命名空间内,它的操作比Monitor使用更简单。

它存在CompareExchange、Decrement、Exchange、Increment等常用方法让参数在安全的情况进行数据交换。

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); }

结束语

熟悉掌握多线程开发,对提高系统工作效率非常有帮助,尤其是回调方法与最近火热的并行编程更应该引起各位的重视。

在下用了较长的时间总结所过的多线程开发方式,希望本篇文章能对各位的学习研究有所帮助,当中有所错漏的地方敬请点评。

对JAVA与.NET开发有兴趣的朋友欢迎加入QQ群:162338858 
本文转自 leslies2  51CTO博客,原文链接:http://blog.51cto.com/79100812/835881

转载地址:http://mmkdl.baihongyu.com/

你可能感兴趣的文章
【14】代理模式(Proxy Pattern)
查看>>
Visual Studio 2013 为C#类文件添加版权信息
查看>>
hdu1025(nlon(n)最长上升子序列)
查看>>
将Linux文件清空的几种方法
查看>>
Centos7使用yum快速安装ansible
查看>>
java例程练习(网络编程[简单网络连接试验])
查看>>
使用 console.time() 计算js代码执行时间
查看>>
test2-1
查看>>
Linux 进程间通信 有名管道(fifo)
查看>>
Oracle中SQL查询表字段基本信息、主键、外键(转)
查看>>
Oracle 12C 新特性之 恢复表
查看>>
Cisco交换机里IP和MAC地址互查找出对应端口
查看>>
随机数
查看>>
201671010117 2016-2017-2 《JAVA程序设计》java第十六周学习心得
查看>>
vue数据更新UI不刷新显示解决方案
查看>>
周例会的作用
查看>>
深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法
查看>>
泛型中的协变
查看>>
1-22
查看>>
alpine 容器优化
查看>>