首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程安全无锁计数器

线程安全无锁计数器
EN

Code Review用户
提问于 2012-08-28 08:01:32
回答 1查看 17.2K关注 0票数 12

我正在使用这样的代码:

代码语言:javascript
复制
class Counter
{
    private int i = 0;

    public int Next()
    {
        lock (this)
        {
            return i++;
        }
    }

    public void Reset()
    {
        lock (this)
        {
            i = 0;
        }
    }

}

我用这样的方式重构了它:

代码语言:javascript
复制
class Counter
{
    private int i = 0;

    public int Next()
    {
        return Interlocked.Increment(ref i);
    }

    public void Reset()
    {
        i = 0;
    }

}

那能行吗?

如果这件事重要的话,我正在使用.NET 4.5。

EN

回答 1

Code Review用户

回答已采纳

发布于 2012-10-27 10:30:45

在.NET的早期版本中,它也应该很好,因为您没有使用任何特定的类或语言特性。

重置是可以的,因为正如您提到的那样,赋值是原子的,但是如果您使用的是long,那么您将需要使用Interlocked.Exchange,因为64位数的赋值在32位操作系统上不是原子的(因为它存储为2 32位值)。

我建议的唯一修改完全是从编码标准的角度出发:

代码语言:javascript
复制
// seal the class as it's not designed to be inherited from.
public sealed class Counter
{
    // use a meaningful name, 'i' by convention should only be used in a for loop.
    private int current = 0;

    // update the method name to imply that it returns something.
    public int NextValue()
    {
        // prefix fields with 'this'
        return Interlocked.Increment(ref this.current);
    }

    public void Reset()
    {
        this.current = 0;
    }
}
票数 9
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/15121

复制
相关文章

相似问题

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