0

我需要知道有多少线程试图进入临界区。我有一个比方说设备的集合,我想获得挂起线程数量最少的设备。

List<Device> devices;
.
.
.

Device device = Device.getAvailableDevice( devices );

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

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

4

2 回答 2

0

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

于 2013-09-24T10:14:06.140 回答
0

你的逻辑有一个根本性的缺陷。

我假设您希望该方法Device.getAvailableDevice( devices )返回实际可用的设备 - 甚至是第一个可用的设备。但是您仅在该呼叫之后锁定设备。这意味着不止一个线程可能会观察到设备可用,然后尝试锁定它。结果,线程确实在队列中等待获取设备,这应该是“可用的”。因此,您会问如何找出有多少人在等待,因为您希望实施该信息Device.getAvailableDevice( devices ),如果没有找到没有人在等待的信息,那么至少要找到即将推出的信息。

相反,您应该做的是创建某种设备管理器,其中包含两个集合:可用设备和正在使用的设备。管理器应该有两种方法:GetAvailableDevice返回可用的设备并将其设置为使用中,以及ReturnDevice使设备再次可用(即,将其从使用中的设备集合移动到可用设备集合)。

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

有关如何实现这种结构的更多信息,我建议您阅读 Joseph Albahari 的“Threading in C#”,参见http://www.albahari.com/threading/

基于每个设备的队列的解决方案需要现在决定哪个设备将在未来忙碌或可用。当它决定时,发生的第一件事是请求它的线程开始等待那个特定的设备(可能是零时间)。

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

于 2013-09-24T10:30:17.160 回答