为什么这个例子中的队列锁是必要的
Why is queue lock in this example necessary
我得到了下面显示的例子。我无法找出为什么在队列 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 )
?
内部锁实际上并不是必需的,因为只要没有再次达到等待时间,锁就会被持有并阻止所有生产者。因此这应该有效:
private void ThreadFunc() {
do {
if( !stop ) {
WorkDelegate workItem = null;
lock( workLock ) {
if( Monitor.Wait(workLock, WaitTimeout) ) {
workItem = (WorkDelegate) workQueue.Dequeue();
}
}
if (workItem != null) workItem();
}
} while( !stop );
}
public void SubmitWorkItem( WorkDelegate item )
{
lock( workLock ) {
workQueue.Enqueue( item );
Monitor.Pulse( workLock );
}
}
Joseph Albahari's site 是线程场景的绝佳参考。
虽然这是一个经典的 producer/consumer 场景,但我建议您使用 BlockingCollection.
我得到了下面显示的例子。我无法找出为什么在队列 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 )
?
内部锁实际上并不是必需的,因为只要没有再次达到等待时间,锁就会被持有并阻止所有生产者。因此这应该有效:
private void ThreadFunc() {
do {
if( !stop ) {
WorkDelegate workItem = null;
lock( workLock ) {
if( Monitor.Wait(workLock, WaitTimeout) ) {
workItem = (WorkDelegate) workQueue.Dequeue();
}
}
if (workItem != null) workItem();
}
} while( !stop );
}
public void SubmitWorkItem( WorkDelegate item )
{
lock( workLock ) {
workQueue.Enqueue( item );
Monitor.Pulse( workLock );
}
}
Joseph Albahari's site 是线程场景的绝佳参考。 虽然这是一个经典的 producer/consumer 场景,但我建议您使用 BlockingCollection.