下面呢,一起看一下线程的同步 刚才我们提到了就是多个线程它可以同时运行,但是呢
有时候线程与线程之间呢,比如说这个线程要做的任务跟另一个线程的任务呢它可能有一-
定的关系 就是要做某种控制,但是这个控制呢相对来说是比较复杂的
我们先看比较简单的一些控制,第一个就是Join方法 它可以把单独执行的另一个线程呢合并到
另一个线程里头,这样使得它就把两个线程合到一个线程来执行
请看这里,这里呢我们有一个线程Thead,这个线程呢里面带一个方法
我们知道呢,这个Delegate呢,就是这个委托啊
它可以直接写这个方法名,它就把它包装成一个委托了,然后
这个thread.Start,这个线程启动了,然后我们用thread.Join,- 那就是把
另一个线程呢,添加到我们这个主线程里面,加入到
当前这个线程里头来,所以这样就实际上,原先本来是两个线程 把它合并成一个线程。
线程控制里头呢,两个线程
都要访问同一个对象,那么这个时候呢就有可能带来一些一系列的问题,比如说两个线程要
访问同一个变量,那这里的时候呢,就有可能带来不一致,这是为什么呢,因为有可能当我们
这个线程里面的这几条指令在执行的时候呢,对某个变量
进行操作,然后CPU呢它切换到另一个线程去了 而另一个线程它又对,也对这个变量进行操作
那本来我们原先那个线程呢,在对这个变量操作的时候呢,还没有达到一个我们需要的效果
然后另一个变量又看见它这个变量了,等于是一个中间状态
那这个时候呢就会带来一系列的不一致性,所以呢,C#里头呢
它就有考虑到这种情况,那么它就做了一件事情呢,就是用一个Lock语句,这个
Lock语句呢它可以对某一个对象,一般都是某一个对象,当然或者是一个表达式的那个对象
对这个对象呢进行锁定,锁定以后呢再执行某些语句,比如说
我们在商场里面,换衣间,试衣间,那这个试衣间必须
是等头一个人出来以后,我们才能第二个人进去,它这个道理有点差不多
就相当于只有第一个人获得这个对象的锁,也就是说获得这个对象的存取权的时候
那它就可以进到,这个线程呢就可以进到这里面的语句去执行
必须等它,这一系列的语句,相关的语句执行好了以后
那别人才能获得这个锁,才能进到这一段代码里来执行 所以这里面这段代码一般都是访问比较关键的一些变量
那这个Lock语句呢它在本质上的实现呢实际上是用了一个Monitor对象,这个Mo- nitor呢
Enter就是进入到,也就是说相当于呢
它取得了这个对象的一个锁,然后我们才可以进入到这里面
所以一句话,就是用Lock语句 以后呢,使得这里面的语句在执行过程当中呢
在同一瞬间只能有一个线程去执行这些语句,当然由于
这个线程同步呢还有一系列的这个对象 这里面呢列举了几个,比如说
自动重置的这个事件,然后呢刚才我们的Monitor,还有一些互斥对象 还有Timer,等等。
另外呢,线程里面呢还有一些实用工具,比如说 线程池,线程的编程是很方便的
但是每创建一个线程 会带来很多的资源的开销,会,也就是
它的代价是很大的,包括我们要做一些很多的准备工作,等等
那所以呢,同时呢我们也不能够说创建很多很多的 线程,这样会带来很大的这个负担
那这样的话,我们就经常有一种办法呢,就是要用线程池,这个线程池呢它里面有一定数- 量的线程
这样呢我们需要的时候呢就可以从里面取一个线程,然后来执行我们的
任务,当我们把这个任务执行完了,这个线程本身,这个对象还不释放
然后呢我们这个对象又可以重用,再做别的事情,这个呢就称为线程池
那线程池呢实际上是系统提高我们线程 利用率的一个好办法。
那系统里面呢它有一个 线程池这个类,TheadPool
它里面有一个QueueUserWorkItem 就把相关的这个任务呢交给它来执行
所以这样的话,也就是说这个线程池你交给它一个任务,它就会想办法 取得一个线程或者新建一个线程,或者利用已有的线程
来执行,另外一些实用工具类呢,比如说Timer类,这个
Timer呢不是我们Winform里面那个Timer,是System.Thread- ing里面的Timer
这个Timer呢它也是相当于每隔一定的时间来执行一定的任务
这个任务呢当然它是一个委托了,就是TimerCallback,就每
在这里呢new了一个Timer对象,这个Timer对象呢 它是每一次要做的事情呢实际上是一个委托
里面包装的一个函数,每一次呢,每隔一定的时间 这里呢是每隔一秒钟然后做一件事情
刚才那个Timer呢跟System.Windows.Forms的Timer呢
还是有所区别的,那刚才那个Timer呢它实际上是没有界面的 那这个实际上是在界面,我们可以呢
从工具箱上面拖过来,把这个Timer对象,然后呢 这也是我反复说的,这我最喜爱的一个对象,Timer
它的属性呢就是Interval,就时间间隔,Enabled呢是否使能,是否起作用
然后它的事件呢就是Tick事件,所以它是用事件的方式来使用的