.NET 9 Preview 1 中的 Lock 类型
Lock 类型 简介
在 .NET 9 预览 1 中,Lock 类型是一个新的值类型,用于在多线程环境中保护共享资源。它旨在比现有的锁机制(例如 Monitor 和 Mutex)更轻便、更高效。目前在 Preview 1 版本中已经可以使用,不过目前还是一个预览版的特性,需要添加System.Runtime.Versioning.RequiresPreviewFeatures 来使用。
代码示例
这样的代码输出结果是什么呢?
{
var sum = 0;
Parallel.For(1, 1001, i =>
{
sum += i;
});
Console.WriteLine(sum);
}
每次运行可能会输出不同的结果,因为这样会有并发问题
我们可以使用 lock 关键词在每次累加的时候同步处理来避免并发问题,大概会是这样
{
var sum = 0;
Parallel.For(1, 1001, i =>
{
lock(nameof(MainTest))
{
sum += i;
}
});
Console.WriteLine(sum);
}
这里出于简单考虑,lock 里直接用了 nameof(MainTest),实际代码最好不要这样写,可以建一个单独的 object 来使用,避免和其他 lock 的地方发生死锁的情况
.NET 9 的 Lock 使用示例如下:
{
// This API requires opting into preview features
varlocker=newLock();
varsum=0;
Parallel.For(1,1001,i=>
{
using(locker.EnterScope())
{
sum+=i;
}
});
Console.WriteLine(sum);
}
最后我们把代码整理到一起并在前面添加一个 Console.WriteLine(Enumerable.Range(1, 1000).Sum()); 来对比输出结果,完整代码如下:
[System.Runtime.Versioning.RequiresPreviewFeatures]
publicstaticclassLockSample
{
public static void MainTest()
{
Console.WriteLine(Enumerable.Range(1, 1000).Sum());
Console.WriteLine();
{
var sum = 0;
Parallel.For(1, 1001, i =>
{
sum += i;
});
Console.WriteLine(sum);
}
{
var sum = 0;
Parallel.For(1, 1001, i =>
{
lock(nameof(MainTest))
{
sum += i;
}
});
Console.WriteLine(sum);
}
{
// This API requires opting into preview features
var locker = new Lock();
var sum = 0;
Parallel.For(1, 1001, i =>
{
using (locker.EnterScope())
{
sum += i;
}
});
Console.WriteLine(sum);
}
}
}
为了体现第一个没有 lock 示例每次输出结果可能不同,执行了三次,输出结果如下:
目前需要添加
System.Runtime.Versioning.RequiresPreviewFeatures attribute 来使用,否则会有编译错误。
3