CodeQL 文档

字段上的无效同步

ID: cs/unsafe-sync-on-field
Kind: problem
Security severity: 
Severity: error
Precision: high
Tags:
   - reliability
   - correctness
   - concurrency
   - external/cwe/cwe-662
   - external/cwe/cwe-366
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

锁定已修改字段的 lock 语句不太可能提供线程安全。这是因为不同的线程只锁定字段的值,而不锁定字段本身。由于字段的值会发生变化,因此不同的线程会锁定不同的对象,因此不是互斥的。

建议

不要锁定字段本身,而应使用专用对象进行锁定。该对象应为 privatereadonly,以确保无法在其他地方修改或锁定它。

示例

在以下示例中,可以在不同线程上同时调用方法 AddItemAddItem 尝试使用 lock 语句保护字段 total。但是,同时使用 AddItem 会导致 total 的值不正确。

class Adder
{
    dynamic total = 0;

    public void AddItem(int item)
    {
        lock (total)     // Wrong
        {
            total = total + item;
        }
    }
}

以下代码通过使用专用对象 mutex 进行锁定来解决此问题。

using System;

class Adder
{
    dynamic total = 0;

    private readonly Object mutex = new Object();

    public void AddItem(int item)
    {
        lock (mutex)    // Fixed
        {
            total = total + item;
        }
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私