【发布时间】:2016-05-15 18:42:24
【问题描述】:
我得到了如下所示的示例。我不知道为什么队列 SyncRoot 上存在锁定,而这两种连贯算法都使用同一个对象完全锁定。
据说需要队列锁。
public class CrudeThreadPool
{
static readonly int MaxWorkThreads = 4;
static readonly int WaitTimeout = 2000;
public delegate void WorkDelegate();
public CrudeThreadPool() {
stop = false;
workLock = new Object();
workQueue = new Queue();
threads = new Thread[ MaxWorkThreads ];
for( int i = 0; i < MaxWorkThreads; ++i ) {
threads[i] =
new Thread( new ThreadStart(this.ThreadFunc) );
threads[i].Start();
}
}
private void ThreadFunc() {
lock( workLock ) {
do {
if( !stop ) {
WorkDelegate workItem = null;
if( Monitor.Wait(workLock, WaitTimeout) ) {
lock( workQueue.SyncRoot ) {
workItem =
(WorkDelegate) workQueue.Dequeue();
}
workItem();
}
}
} while( !stop );
}
}
public void SubmitWorkItem( WorkDelegate item ) {
lock( workLock ) {
lock( workQueue.SyncRoot ) {
workQueue.Enqueue( item );
}
Monitor.Pulse( workLock );
}
}
public void Shutdown() {
stop = true;
}
private Queue workQueue;
private Object workLock;
private Thread[] threads;
private volatile bool stop;
}
锁定队列SyncRoot,即lock(workQueue.SyncRoot )的原因是什么?
【问题讨论】:
-
你从哪里得到那个代码,你为什么认为它甚至可以工作?
-
该代码绝对有效。它来自一本教科书。
-
如果您尝试多次实际运行此代码,您会发现它已损坏。您排队 10 个项目,但随机数量的项目得到处理。有时 10,有时 8,有时 4,有时 0。写它的人不明白他在做什么(尤其是 Monitor.Pulse 和 Monitor.Wait 是如何工作的),所以没有太多理由讨论他为什么锁定队列访问。
-
这只是一个例子。绝对不需要处理任何特定数量的项目。
-
此代码已损坏,因为您可能从不处理放入队列的项目。如果你放了 10 件物品——除了它们之外,你至少要在将来的某个时间处理它们。这段代码不是这样。使用损坏的代码,您可以添加或删除队列锁定 - 没关系。
标签: c# multithreading locking syncroot