如何获取阻塞的线程计数器尝试在C#中输入锁定部分

时间:2013-09-24 10:08:54

标签: c# multithreading

我需要知道有多少线程尝试进入关键部分。我有一个让我们说设备的集合,我想得到具有最少量挂起线程的设备。

List<Device> devices;
.
.
.

Device device = Device.getAvailableDevice( devices );

lock (device)
{
     device.DoSomeWork();
}

我知道我可以使用一些计数器,但我试图避免它。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

据我所知,除了使用计数器之外别无他法。 在锁定之前递增它并在锁定块之后减少它。

答案 1 :(得分:0)

你的逻辑存在根本性缺陷。

我假设你打算让方法Device.getAvailableDevice( devices )返回一个实际可用的设备 - 甚至是第一个可用的设备。但是你只能在那次通话后锁定设备。这意味着多个线程可能会观察到设备可用,并随后尝试锁定它。结果,线程确实在队列中等待获取设备,该设备应该是“可用的”。结果,你问你怎么能找出有多少人正在等待,因为你希望这些信息能够实现Device.getAvailableDevice( devices ),如果没有找到一个没有人等待的信息,那么至少找到一个会等待的信息。很快就会上市。

你应该做的是创建某种设备管理器,它拥有两个集合:可用的设备和正在使用的设备。管理员应该有两种方法:GetAvailableDevice返回可用的设备并将其设置为正在使用,ReturnDevice使设备再次可用(即将其从正在使用的设备集合中移除)到可用的设备集合。)

这两种方法锁定设备管理器,但不锁定单个设备。 GetAvailableDevice调用正在阻塞,线程可能正在等待管理器返回一个。 ReturnDevice调用没有阻塞,因为它立即返回。

有关如何实现此类结构的更多信息,我建议您阅读Joseph Albahari撰写的“C#中的线程化”,请参阅http://www.albahari.com/threading/

基于每个设备的队列的解决方案需要立即决定将来哪个设备将忙或可用。当它决定时,首先发生的事情是请求它的线程开始等待该特定设备(可能是零时间段)。

基于单个队列的所有设备组合的解决方案无需预测未来。随着设备变得可用,任何设备,它都会将其提供给可以立即开始使用它的等待线程。线程等待设备管理器为它们提供一个设备(可能是零时间段),但不是给予它们的设备。此解决方案还避免了线程仍在等待设备的情况,而另一个设备已经可用,没有线程等待它。