一:锁机制
1.net锁机制
时间锁、信号锁、互斥锁、读写锁、互锁,易变构造
分类:
- 用户模式锁:通过一些cpu指令或者一个死循环达到thread等待和休眠。
- 内核模式锁:调用win32底层的代码,来实现thread的各种操作,如:Thread.Sleep
- 混合锁:用户模式+内核模式
2.为什么要用锁?
多线程对一个共享资源进行操作的时候,容易出现共享资源混乱的问题
二:用户模式锁
解决问题:
Thread.MemoryBarrier, Thread.VolatileRead
关键字:volatile
不可以底层对代码进行优化
我的Read和Write都是从memrory中读取,读取的数据是最新的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public static volatile bool isStop = false;
static void Main(string[] args)
{
var t = new Thread(()=> {
var isSuccess = false;
while (!isStop)
{
isSuccess = true;
}
});
t.Start();
Thread.Sleep(1000);
isStop = true;
t.Join();
Console.WriteLine("主线程执行结束!");
Console.ReadKey();
}
2.互锁结构:Interlocked[还只能做一些简单类型计算]
Interlocked:
Increment:自增
var sum = 0; for (int i = 0; i < 10; i++) { Interlocked.Increment(ref sum); } //最后sum=10,自增单位为1
Decrement:自减
1
2
3
4
5
6var sum = 0;
for (int i = 0; i < 10; i++)
{
Interlocked.Decrement(ref sum);
}
//最后sum=-10,自减单位为1
Exchange:赋值
1
2
3var sum = 5;
Interlocked.Exchange(ref sum,10);
//最好sum=10;Add:增加指定的值
1
2
3var sum = 5;
Interlocked.Add(ref sum,2);
//最好sum=7CompareExchange:比较赋值
var sum = 5; Interlocked.CompareExchange(ref sum, 6, 5); //如果sum==5,true:sum=6,false=5;
3.旋转锁:Soinlock
特殊的业务逻辑让thread在用户模式下进行自选,欺骗cpu当前thread正在运行中
用户模式—>内核模式—>用户模式
1 | public static SpinLock spinLock = new SpinLock(); |
SpinLock 仅当您确定这样做可以改进应用程序的性能之后才能使用。另外,务必请注意 SpinLock 是一个值类型(出于性能原因)。因此,您必须非常小心,不要意外复制了 SpinLock 实例,因为两个实例(原件和副本)之间完全独立,这可能会导致应用程序出现错误行为。如果必须传递 SpinLock 实例,则应该通过引用而不是通过值传递。
不要将 SpinLock 实例存储在只读字段中
当锁是细粒度的并且数量巨大(例如链接的列表中每个节点一个锁)时以及锁保持时间总是非常短时,旋转可能非常有帮助