首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在本例中需要队列锁?

为什么在本例中需要队列锁?
EN

Stack Overflow用户
提问于 2016-05-15 18:42:24
回答 1查看 1.9K关注 0票数 2

我有下面的例子。我也找不出为什么队列SyncRoot也有锁,而这两种相干算法都使用相同的对象进行了完全锁定。

据说队列锁是必要的。

代码语言:javascript
复制
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 )

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-15 18:52:59

内部锁实际上并不是必需的,因为只要没有再次到达等待,锁就会被保持,并将阻止所有生产者。因此,这应该是可行的:

代码语言:javascript
复制
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 );
    }
}

对于线程处理场景,约瑟夫·阿尔巴哈里遗址是一个很棒的参考。虽然这是一个典型的生产者/消费者场景,但我建议您使用BlockingCollection

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37242257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档