ManualResetEvent
new ManualResetEvent(true) //一开始不阻塞
WaitOne();//等待信号
Reset(); //线程会阻塞在WaitOne调用的位置 (一般我喜欢将这个封装一下,命名为Lock,Set则为Unlock
Set();//线程不会阻塞,WaitOne直接通过
AutoResetEvent
new AutoResetEvent(false) //一开始不阻塞,这里和Manual是相反的
调用一次Set,解除阻塞,当WaitOne通过一个线程后,自动再次阻塞,相当于内部自动Reset了
Mutex
类似AutoResetEvent
ReleaseMutex(Set)的时候释放
有一个线程通过WaitOne就会立刻阻塞(Reset)
lock
常见的有lock一个static object或者object
静态与否主要取决于关心的内容是静态变量还是当前实例的变量
Monitor
lock(obj)本身就相当于
Monitor.Enter(obj);
Monitor.Exit(obj);
Interlocked
线程安全的简单的变量操作
public int State
{
get => Interlocked.Increment(ref _state);
}
SpinLock
C#线程锁(自旋锁SpinLock、互斥锁Mutex、混合锁Monitor | lock)_xujianjun229的博客-CSDN博客_c# 线程锁
自旋锁是指当一个线程在获取锁对象的时候,如果锁已经被其它线程获取,那么这个线程将会循环等待,不断的去获取锁,直到获取到了锁。适合于原子操作时间非常短的场景
优点:避免了线程上下文切换。性能较高。
缺点:如果长时间等待,将消耗大量的CPU资源。而且多个等待中的线程,并不是等待时间越长就先获取到锁,可能会一直等待下去。
private static SpinLock _spinLock = new SpinLock();
private static int incrValue = 0;//共享资源
private void Run()
{
bool locked = false;
_spinLock.Enter(ref locked);//获取锁
incrValue++; //安全的逻辑计算
if (locked) //释放锁
_spinLock.Exit();
}
ReaderWriterLockSlim 读写锁
.NET 同步与异步之锁(ReaderWriterLockSlim)(八)_mb5fe09d2d96fc4的技术博客_51CTO博客
ReaderWriterLockSlim.EnterUpgradeableReadLock Method (System.Threading) |微软文档 (microsoft.com)
EnterUpgradeableReadLock主要是用于,需要读,还要写的情况
SemaphoreSlim
构造的时候设置一个数量,限制进入的线程数
SemaphoreSlim 类 (System.Threading) | Microsoft Docs
CancellationTokenSource
这个倒不是锁。刚好看到 顺便记录一下。
C# 使用CancellationTokenSource取消多线程_tnblog技术分享~的博客-CSDN博客_cancellationtokensource
CancellationTokenSource cts = new CancellationTokenSource();
在线程中执行主要逻辑之前调用:
cts.Token.ThrowIfCancellationRequested();
在某处调用了 cts.Cancel(true);
当线程执行到ThrowIfCancellationRequested的位置,会抛出异常,直接退出线程
如果线程已经执行到ThrowIfCancellationRequested之后了,cts就起不了作用了。