Vb.net 我应该在代码中同步什么,在哪里?
我有一个类,其中有两个方法,一个调用一个类,该类创建并执行多个线程,另一个是一个事件处理程序,它处理这些线程完成时引发的事件(然后再次调用第一个方法) 我知道处理事件的方法在引发事件的线程中运行。因此,IVb.net 我应该在代码中同步什么,在哪里?,vb.net,multithreading,thread-safety,synclock,Vb.net,Multithreading,Thread Safety,Synclock,我有一个类,其中有两个方法,一个调用一个类,该类创建并执行多个线程,另一个是一个事件处理程序,它处理这些线程完成时引发的事件(然后再次调用第一个方法) 我知道处理事件的方法在引发事件的线程中运行。因此,ISyncLock一个成员变量,表示有多少线程正在运行,并从中减去一个: SyncLock Me ' GetType(me) _availableThreads -= 1 End SyncLock 所以我有几个问题: 主要问题:我是否应该同步\u可用读取类中的所有位置,即在创建线程的方法
SyncLock
一个成员变量,表示有多少线程正在运行,并从中减去一个:
SyncLock Me ' GetType(me)
_availableThreads -= 1
End SyncLock
所以我有几个问题:
主要问题:我是否应该同步\u可用读取类中的所有位置,即在创建线程的方法中(创建线程时添加1)
与此问题相关的补充问题:
我通常会SyncLock
当前实例,但我见过SyncLock
s类型的代码,那么同步锁定Me
(当前实例)和GetType(Me)
之间的区别是什么呢
两者之间会有性能差异吗?还有什么更小的东西我可以为上面的内容锁定,而不影响其他任何东西——可能是一个单独的“挂锁”对象,它的唯一目的是锁定类中的东西
注意:\u availableThreads
的唯一目的是控制在任何给定时间可以运行的线程数量,以及线程处理可能需要数小时才能运行的作业
代码:
公共类QManager
Private _maxThreadCount,_AvailableThread读取为整数
Public Sub New(ByVal maxThreadCount为整数)
Me.MaximumThreadCount=maxThreadCount
端接头
公共子工作队列()
//从队列中获取作业(优先级更改,所以每次都调用此选项)
Dim jobQ As Queue(QdJobInfo的)=QueueDAO.GetJobList
//在有作业且我们有可用线程时循环作业队列
当jobQ.Count>0且_availableThreads时,不应SyncLock
实例或类型。您总是希望对完全在类控制范围内的变量进行SyncLock
,而这两个变量都不是。您应该声明一个私有的新对象
,并将其用于同步锁
Private lockObject as New Object()
这里应该使用Interlocked类,Decrement()方法来减少计数。是的,无论在哪里访问变量
使用SyncLock Me与SyncLock GetType(Me)一样糟糕。您应该始终使用私有对象来锁定,以便没有人会意外导致死锁。黄金法则是不能锁定数据,只能阻止代码访问数据。因为代码是您的私有实现细节,所以保存锁状态的对象也必须是私有细节。您的对象(我)或该对象的类型都不是私有的。意外地允许其他代码锁定它。不幸的是,您需要在这里做一些不同的事情
首先,我建议避免使用SyncLock,并使用Interlocked.Increment和Interlocked.decreation来处理可用读取的更改。这将为没有锁的变量提供线程安全性
也就是说,如果队列是从多个线程使用的,那么对队列的每次访问都需要一个同步锁。如果您使用的是.NET4,另一种选择是改用新类而不是队列。如果使用SyncLock,则应创建一个只能由类访问的私有对象,并将其用于所有同步。您可以用信号量替换线程计数器。若使用信号量,则无需退出while循环,也无需从ThreadCompleted事件处理程序调用WorkThroughQueue()。信号量是线程安全的,所以您可以在不锁定的情况下使用它
非常有趣。。。我不知道这个互锁的类。谢谢。@Shoubs先生:不,不太好。如果您使用的是3.5,我建议您在私有对象上使用同步锁来访问队列,包括入队列和出队列。@Shoubs先生:只要您在队列完成之前不阻塞,就可以了。一旦线程的函数返回,线程就会消失,并有资格被垃圾收集。@Shoubs先生:看起来queuedJob.Process()启动了一个新线程。如果是这种情况,只要该方法返回,WorkThroughQueue就会返回,线程就会“消失”@Shoubs先生:在创建新线程后,逻辑将继续,旧线程就会消失,通常。。。但是,如果不看代码就很难知道。这是一个很好的信息,谢谢!我将研究我正在使用的方法和信号量,因为我也想了解如何连接线程。
Private lockObject as New Object()
SyncLock lockObject
...
End SyncLock