.NET 6 新特性 —— Random.Shared
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET 6 新特性 —— Random.Shared相关的知识,希望对你有一定的参考价值。
.NET 6 新特性 —— Random.Shared
Intro
最近微软发了一篇 .NET 6 性能提升的博客文章,里面提到了很多有趣的东西,其中有一个是 Random.Shared
这是一个只读的静态属性,并且是一个线程安全的对象,这个东西可以帮助我们简化 Random
对象的使用
Before
首先我们需要知道 Random
不是线程安全的,所以我们如果要在多线程下用 Random
的话,通常需要考虑线程安全问题
既然不是线程安全的,那我们用的时候创建一个就好了,每次都 new 一个,但是这样的话一来代码不够简洁,二来可能会创建比较多的 Random
对象,那么不使用的时候每次 new 要怎么做呢?
比较简单的做法就是加一个锁,如下所示:
public static class RandomGen1
{
private static Random _inst = new Random();
public static int Next()
{
lock (_inst) return _inst.Next();
}
}
但是这样的话会导致获取锁的效率相对来说会比较低,每次还需要去先拿到锁,所以也有别的解法:
public static class RandomGen2
{
private static Random _global = new Random();
[ThreadStatic]
private static Random _local;
public static int Next()
{
Random inst = _local;
if (inst == null)
{
int seed;
lock (_global) seed = _global.Next();
_local = inst = new Random(seed);
}
return inst.Next();
}
}
上面是一个微软推荐的实现,那么为什么要两个 Random
对象呢,Random
对象产生随机数依赖于一个 seed,默认是使用当前时间,如果时间特别接近的话,会发现即使是不同的 Random 对象产生的随机数有可能是一样的
上面的 _global
对象是用于产生随机的 seed,避免使用默认的 seed,_local
是一个被标记为 ThreadStatic
的对象,每一个线程会拥有一个单独的 Random
对象从而避免线程安全问题。
Sample
有了 Random.Shared
之后,我们就不需要上面的封装了
Console.WriteLine(Random.Shared.Next(1, 100));
Parallel.For(0, Environment.ProcessorCount, _ =>
{
var thread = new Thread(() =>
{
var arr = new int[10];
for (var i = 0; i < arr.Length; i++)
{
arr[i] = Random.Shared.Next(1, 100);
}
Console.WriteLine(arr.Average());
});
thread.Start();
});
Random.Shared
的实现也是类似于上面的 ThreadStatic
的解法,但是是从 CLR 的底层去实现的,会比上面的实现方式更为高效,实现代码可以参考 Github:https://github.com/dotnet/runtime/blob/v6.0.0-preview.7.21377.19/src/libraries/System.Private.CoreLib/src/System/Random.cs
More
使用新的 Random.Shared
对象之后就移除掉代码中大量的 new Random
或者自己封装的 Random
了,代码更加简洁了~~
References
https://github.com/dotnet/runtime/issues/43887
https://github.com/dotnet/runtime/pull/50297
https://github.com/dotnet/runtime/pull/50297/files#diff-6fa7e54f57878bb019a11332aeeb42c75430a0ac87c78cdfa9ce382137b3d851R51
https://github.com/dotnet/runtime/blob/v6.0.0-preview.7.21377.19/src/libraries/System.Private.CoreLib/src/System/Random.cs
https://devblogs.microsoft.com/pfxteam/getting-random-numbers-in-a-thread-safe-way/
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/
以上是关于.NET 6 新特性 —— Random.Shared的主要内容,如果未能解决你的问题,请参考以下文章