多线程 互斥锁与读写锁 概念
一、多线程 lock 互斥锁
简述
多线程环境中,不使用lock锁,会形成竞争条件,导致A线程与B线程数据使用冲突。
使用lock锁可以保证当有线程操作某个共享资源时,能使该代码块按照指定的顺序执行,其他线程必须等待直到当前线程完成操作。
即是多线程环境,如果一个线程锁定了共享资源,需要访问该资源的其他线程则会处于阻塞状态,并等待直到该共享资源接触锁定。
private static object Lock = new object();
static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
private int a = 0;
async void Start()
{
for(int i = 0; i < 100000; i++)
{
_ = GetA();
}
await UniTask.Delay(5000);
Debug.Log("A = " + a);
}
async Task GetA()
{
//独立线程运行
await Task.Run(() =>
{
//加 lock 加锁后后面则等待 上一个线程使用完毕后解锁+=1
//lock(Lock)
//{
// a += 1;
//}
//不加Lock 执行 可能会出现2个线程同时100+=1
a += 1;
});
}
二、多线程 读写锁
简述
多线程读写锁是一种并发控制机制,用于处理多个线程同时读取共享数据和写入共享数据的情况。该机制允许多个线程同时读取共享数据,但只允许一个线程写入共享数据。这可以提高程序的并发性和性能。
读写锁包含两个锁:读锁和写锁。多个线程可以同时获取读锁,但只有一个线程可以获取写锁。当一个线程持有写锁时,其他线程无法获取读锁或写锁。
读写锁的优点在于,当多个线程只读取共享数据时,可以同时获取读锁,从而避免了互斥锁的性能开销。而当一个线程需要写入共享数据时,它必须获取写锁,这会阻塞其他线程的读写操作,从而保证了数据的一致性。
读写锁的缺点在于,当一个线程拥有写锁时,其他线程无法读取或写入共享数据,可能会导致一些线程长时间的等待。此外,由于读写锁需要维护多个锁状态,因此在实现上比互斥锁更复杂。
async Task GetA()
{
await Task.Run(() =>
{
//当 rwl 进入写锁时 读锁 写锁都需要等待
rwl.EnterWriteLock();
Debug.Log(a);
rwl.ExitWriteLock();
});
}
async Task GetB()
{
await Task.Run(() =>
{
//当 rwl 进入读锁时 写锁需要等待,所有读锁无需等待
rwl.EnterReadLock();
Debug.Log(a);
rwl.ExitReadLock();
});
}
async Task GetC()
{
await Task.Run(() =>
{
//当 rwl 进入读锁时 写锁需要等待,所有读锁无需等待
rwl.EnterReadLock();
Debug.Log(a);
rwl.ExitReadLock();
});
}
本文作者:晨冰
本文链接:https://www.cnblogs.com/wjc666/p/17268259.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
———小知识———
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步