首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程化测试题

线程化测试题
EN

Stack Overflow用户
提问于 2011-07-08 06:35:09
回答 3查看 1.4K关注 0票数 8

我最近在一个类似下面的测试中有一个面试问题,我没有太多使用线程开发的经验,有人能帮我建议如何处理这个问题吗?

代码语言:javascript
复制
public class StringQueue
{
    private object _lockObject = new object();

    private List<string> _items = new List<string>();

    public bool IsEmpty()
    {
        lock (_lockObject)
            return _items.Count == 0;
    }

    public void Enqueue(string item)
    {
        lock (_lockObject)
            _items.Add(item);
    }

    public string Dequeue()
    {
        lock (_lockObject)
        {
            string result = _items[0];
            _items.RemoveAt(0);

            return result;
        }
    }
}

在上面的实现中,下面的方法线程安全吗?为什么?

代码语言:javascript
复制
public string DequeueOrNull()
{
    if (IsEmpty())
        return null;

    return Dequeue();
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-08 06:41:31

在我看来,答案是否定的。

虽然isEmpty()过程会锁定对象,但只要调用返回,它就会被释放--另一个线程可能会在调用IsEmpty()和Dequeue()之间调用DequeueOrNull() (此时对象处于解锁状态),从而删除唯一存在的项,从而使Dequeue()在当时无效。

一种合理的解决方法是将锁放在DequeueOrNull()中的两个语句上,这样在检查之后但在DeQueue()之前没有其他线程可以调用DeQueue()。

票数 9
EN

Stack Overflow用户

发布于 2011-07-08 06:43:01

它不是threadsafe。在标记的行上,Dequeue方法可能是从另一个线程调用的,因此,后续的Dequeue返回一个错误的值:

代码语言:javascript
复制
public string DequeueOrNull()
{
    if (IsEmpty())
        return null;
///  << it is possible that the Dequeue is called from another thread here.
    return Dequeue();
}

线程安全代码为:

代码语言:javascript
复制
public string DequeueOrNull()
{
  lock(_lockObject) {
    if (IsEmpty())
        return null;
    return Dequeue();
  }
}
票数 3
EN

Stack Overflow用户

发布于 2011-07-08 06:41:59

不会,因为_items的状态可能会在线程安全的IsEmpty()调用和线程安全的Dequeue()调用之间发生变化。

如下所示进行修复,以确保_items在整个操作过程中处于锁定状态:

代码语言:javascript
复制
public string DequeueOrNull()
{
  lock (_lockObject)
  {
    if (IsEmpty())
      return null;

    return Dequeue();
  }
}

注意:根据_lockimplementation,您可能希望通过将IsEmpty()Dequeue的内部移动到单独的助手函数中来避免双重锁定资源。

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

https://stackoverflow.com/questions/6617948

复制
相关文章

相似问题

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