版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
如上一节《vb.net 教程 6-16 使用SyncLock语句实现线程的同步 》介绍的SyncLock语句,是一种简单处理同步的方法。
.net还提供了Monitor类处理线程同步。Monitor类比较重要的几个静态方法:
Enter 在指定对象上获取排他锁。
Exit 释放指定对象上的排他锁。
TryEnter 尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。
Monitor的Enter和Exit方法有点类似于SyncLock和End SyncLock。这里重点介绍TryEnter方法。
TryEnter方法的一个重载:
Public Shared Function TryEnter ( _
obj As Object, _
millisecondsTimeout As Integer _
) As Boolean
参数:
obj 在其上获取锁的对象。
millisecondsTimeout 等待锁所需的毫秒数,即在 millisecondsTimeout 毫秒后释放这个锁,不会一直占有,这样其他线程也可以继续下去。
使用Enter或者TryEnter方法时候,锁定的对象所需要满足的条件和SyncLock 的lockobject一样,具体请参看《vb.net 教程 6-16 使用SyncLock语句实现线程的同步 》
下面将用一个例子说明Monitor类的使用:
使用Monitor类也需要先定义一个模块级变量(只针对本代码):
Private MonitorObj As Object
主代码:
Sub sample13()
MonitorObj = New Object
For i As Integer = 0 To 5
Dim sample13_Thread As New Thread(AddressOf sample13_doALoop1)
sample13_Thread.Start(i)
Next
Thread.Sleep(100)
Console.ReadKey()
End Sub
Sub sample13_doALoop1(ByVal number As Integer)
Dim counter As Integer = CType(number, Integer)
Monitor.TryEnter(MonitorObj, 100)
For i As Integer = 1 To 100
Console.Write(" " & counter)
Next
Monitor.Exit(MonitorObj)
End Sub
OK,运行,开始输出。
然后,大概率会出错:
Monitor 引发 了SynchronizationLockException错误,并显示消息“从不同步的代码块中调用了对象同步方法”。
msdn给出的说明是:当要求调用方拥有给定 Monitor 的锁的方法被没有该锁的调用方调用时引发的异常。
推测是因为主线程休息的时间太短,抢用Console资源,和Monitor锁定内容中的资源冲突。
可以通过将Thread.Sleep(100)修改为更多毫秒数来避免出错,或者使用以下改进的代码:
Sub sample13()
MonitorObj = New Object
For i As Integer = 0 To 5
Dim sample13_Thread As New Thread(AddressOf sample13_doALoop2)
sample13_Thread.Start(i)
Next
Thread.Sleep(100)
Console.ReadKey()
End Sub
'修改后的例子
Sub sample13_doALoop2(ByVal number As Integer)
Dim counter As Integer = CType(number, Integer)
Try
Monitor.TryEnter(MonitorObj, 1000) '这里的时间不能设置太短,否则会在Exit处发生错误。
For i As Integer = 1 To 100
Console.Write(" " & counter)
Next
Catch ex As Exception
Finally
Monitor.Exit(MonitorObj)
End Try
End Sub
由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。
学习更多vb.net知识,请参看 vb.net教程 目录
————————————————
版权声明:本文为CSDN博主「VB.Net」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。