SyncLock 语句
来源:互联网 发布:淘宝拍摄摄影棚的搭建 编辑:程序博客网 时间:2024/05/16 17:24
SyncLock 语句
SyncLock 语句使语句得以在表达式上同步,这确保了多个执行线程不会同时执行同一个语句。在进入块后,表达式计算一次。进入SyncLock 块时,在指定的表达式上调用 Shared 方法 System.Monitor.Enter,该方法一直阻塞到执行线程在表达式返回的对象上具有独占锁。SyncLock 语句中的表达式类型必须为引用类型。
SyncLock 块隐式地包含在 Try 语句中,该语句的Finally 块在表达式上调用 Shared 方法 System.Monitor.Exit。这确保了即使在引发异常时仍会释放锁。因此,从SyncLock 块的外部分支到该块是无效的。
由于 SyncLock 块使用结构化异常处理,而且结构化异常处理不能同非结构化异常处理混用,因此在使用非结构化异常处理的方法中有SyncLock 块是无效的。
类的 System.Type 对象可方便地用作该类 Shared 方法的锁,如下例所示:
Class Cache Private Shared Sub Add(x As Object) SyncLock GetType(Cache) End SyncLock End Sub Private Shared Sub Remove(x As Object) SyncLock GetType(Cache) End SyncLock End SubEnd Class
SyncLockStatement ::=(SyncLock 语句 ::=)
SyncLock Expression StatementTerminator(SyncLock 表达式语句结束符)
[ Block ]([ 块 ])
End SyncLock StatementTerminator(End SyncLock 语句结束符)
-----------------------------------------------------------------------------------------------------------------------------
在执行一个语句块前获取此块的独占锁。
SyncLock lockobject [ block ]End SyncLock
- lockobject
必选。计算结果等于对象引用的表达式。
- block
可选。获取独占锁时要执行的语句块。
- End SyncLock
终止 SyncLock 块。
SyncLock 语句确保不会同时有多个线程执行该语句块。SyncLock 防止各个线程进入该语句块,直到没有其他线程执行它为止。
SyncLock 的最常见作用是保护数据不被多个线程同时更新。如果操作数据的语句必须在没有中断的情况下完成,请将它们放入SyncLock 块。
有时将受独占锁保护的语句块称为“临界区”。
规则
分支。您不能从此块的外部分支到 SyncLock 块。
锁定对象值。lockobject 的值不能为Nothing。必须先创建锁定对象,才能在 SyncLock 语句中使用此对象。
在执行 SyncLock 块时,不能更改 lockobject 的值。机制要求锁定对象保持不变。
行为
机制。线程到达 SyncLock 语句时,它将计算 lockobject 表达式,并挂起执行,直到获取了由表达式返回的对象上的独占锁。当另一线程到达 SyncLock 语句时,它将不能获取独占锁,直到第一个线程执行End SyncLock 语句。
受保护的数据。如果 lockobject 为Shared 变量,独占锁将防止类的任何实例中的线程在任何其他线程执行 SyncLock 块时执行该块。这会保护所有实例所共享的数据。
如果 lockobject 为实例变量(非Shared),此锁将防止当前实例中正在运行的线程与相同实例中的另一线程同时执行 SyncLock 块。这会保护由单个实例维护的数据。
捕获和释放。SyncLock 块的操作就像 Try...Finally 结构,其中Try 块获取 lockobject 上的独占锁,而 Finally 块则释放此锁。因此,SyncLock 块确保锁的释放,不管您如何退出块。即使发生未处理的异常,也是如此。
Framework 调用。SyncLock 块通过调用 System.Threading 命名空间中的Monitor 类的 Enter 方法和 Exit 方法获取和释放独占锁。
编程惯例
lockobject 表达式应始终计算仅属于您的类的对象。您应该声明一个Private 对象变量,以保护属于当前实例的数据,或声明一个 Private Shared 对象变量,以保护所有实例共有的数据。
不应使用 Me 关键字为实例数据提供锁定对象。如果类之外的代码引用了您的类的实例,它可以使用该引用作为SyncLock 块的锁定对象(与您的锁定对象完全不同),从而保护不同数据。通过这种方式,您的类和其他类将相互阻止执行与它们无关的SyncLock 块。由于使用相同字符串的进程中的任何其他代码将共享相同的锁,所以对一个字符串进行相似锁定可能会有问题。
也不应使用 Me.GetType 方法为共享数据提供锁定对象。这是因为GetType 始终为给定类名称返回相同的 Type 对象。外部代码可以调用您的类上的 GetType,并可以获取与您正在使用的锁定对象相同的锁定对象。这将导致两个类相互阻止它们的 SyncLock 块。
下面的示例演示维护简单消息列表的类。它将消息保存在数组中,并将最近使用的该数组的元素保存在变量中。addAnotherMessage 过程增加最近使用的元素,并存储新消息。这两个操作受到SyncLock 和 End SyncLock 语句的保护,因为一旦增加了最近的元素,就必须先存储新消息,然后任何其他线程才可以再次增加最近的元素。
Public messagesList() As String = NewString(50) {}
Public messagesLast As Integer = -1
Private messagesLock As New Object
Public Sub addAnotherMessage(ByVal newMessageAs String)
SyncLock messagesLock
messagesLast += 1
messagesList(messagesLast) = newMessage
End SyncLock
End Sub
End Class
如果 simpleMessageList 类在其所有实例中共享一个消息列表,则变量messagesList 和 messagesLast 将被声明为 Shared。此时,变量messagesLock 也应为 Shared,从而每个实例都将使用单个锁定对象。
- SyncLock语句
- SyncLock 语句
- VB中的SyncLock
- SyncLock GetType(Sum) '定义独占锁
- vb.net 多线程与SyncLock锁
- [Thread] 執行緒同步資源鎖定 – lock / SyncLock
- 语句
- 语句
- 语句
- 语句
- 语句
- 语句
- 语句
- ?:语句
- 语句
- 语句
- 语句
- 语句
- [转]VS2008、DDK XP和DDKWizard搭建驱动开发环境,下载
- OpenCV错误:INK : fatal error LNK1104: cannot open file "cvaux.lib"
- [VMware]关于VMware出现Not enough physical memory is available to power on this virtual machine
- Android系统内存不足时,组建回收顺序问题
- 抱怨IT公司人才缺乏?留住现有人才方是正途
- SyncLock 语句
- Vim小技巧
- 高贵的自由
- what the difference between __weak and __block reference?
- JavaScript世界的一等公民 - 函数
- .net创建XML文件的两种方法
- Android:如何使用addJavaScriptInterface
- JAVA集合框架图
- Android 实现书籍翻页效果----升级篇