You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现含Read、Write方法的Resources类满足指定并发约束

核心实现思路

这是典型的读写锁适用场景,刚好匹配你提出的三个约束,核心逻辑如下:

  • 维护一个正在读取的线程数计数器,初始值为0
  • 维护一个写操作执行中的标志位/排他锁,保证同一时间最多只有一个写线程执行
  • Read()方法执行逻辑:
    1. 先判断当前是否有写操作正在执行,如果有则阻塞等待,直到写操作结束
    2. 进入读操作前,原子性将读线程计数器+1
    3. 执行读业务逻辑
    4. 读操作结束后,原子性将读线程计数器-1,如果减完后计数器归0,通知等待的写线程可以执行
  • Write()方法执行逻辑:
    1. 先获取排他锁,阻塞其他写线程进入
    2. 等待所有正在执行的读线程全部结束,即读线程计数器归0
    3. 执行写业务逻辑
    4. 释放排他锁,通知等待的读/写线程可以执行

工业级实现优先用语言内置的读写锁工具类即可,不需要手动手写,避免出现锁顺序错误、信号量遗漏等并发问题:Java可使用ReentrantReadWriteLock、C#可使用ReaderWriterLockSlim、Go可使用sync.RWMutex。


代码示例(C#版本)

内置类实现(推荐)

public class Resources {
    // .NET内置的读写锁实现,性能和安全性都优于手写实现
    private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();

    public void Read() {
        // 进入读锁,允许多个线程同时获取
        _rwLock.EnterReadLock();
        try {
            // 此处编写读业务逻辑
        }
        finally {
            // 必须在finally块释放锁,避免异常导致锁泄漏
            _rwLock.ExitReadLock();
        }
    }

    public void Write() {
        // 进入写锁,同一时间仅一个线程能获取,且会阻塞所有读锁获取请求
        _rwLock.EnterWriteLock();
        try {
            // 此处编写写业务逻辑
        }
        finally {
            _rwLock.ExitWriteLock();
        }
    }
}

手写实现(学习用)

public class Resources {
    private readonly object _lock = new object();
    private int _readCount = 0;
    private bool _isWriting = false;

    public void Read() {
        lock (_lock) {
            // 有写操作正在执行则等待
            while (_isWriting) {
                Monitor.Wait(_lock);
            }
            _readCount++;
        }

        try {
            // 此处编写读业务逻辑
        }
        finally {
            lock (_lock) {
                _readCount--;
                if (_readCount == 0) {
                    // 读线程全部退出,通知等待的写线程
                    Monitor.PulseAll(_lock);
                }
            }
        }
    }

    public void Write() {
        lock (_lock) {
            // 有写操作在执行、或者有读线程在读则等待
            while (_isWriting || _readCount > 0) {
                Monitor.Wait(_lock);
            }
            _isWriting = true;
        }

        try {
            // 此处编写写业务逻辑
        }
        finally {
            lock (_lock) {
                _isWriting = false;
                // 通知所有等待的读/写线程
                Monitor.PulseAll(_lock);
            }
        }
    }
}

注意事项

  • 上面的手写实现是读优先模式,也就是如果一直有读线程进入,写线程可能会出现饥饿,如果需要公平调度,可以额外增加等待写线程的计数,读线程发现有等待的写线程时主动让路即可。
  • 所有锁的释放必须放在finally块中,避免业务逻辑抛出异常时锁未释放,导致死锁。

内容的提问来源于stack exchange,提问作者rshubh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:27:03