.net core 多线程下使用 Random 会出现的bug

先看原文:

Working with System.Random and threads safely in .NET Core and .NET Framework

https://andrewlock.net/building-a-thread-safe-random-implementation-for-dotnet-framework/

我的结论:

.net 6 之前,如果习惯构建了一个静态的 Random 对象,然后业务代码里直接使用 random.Next() 方法,多线程竞争下,会有一定概率返回0。

.net 6 时,修正了这个默认创建时的多线程存在的bug。但又没完全解决。如果这个公共的 Random 方法初始化的适合使用了自定义随机种子,则还是会存在多线程竞争下出现返回0情况。

原文提供了在 .net 6 之前版本的一些解决办法,我的建议是使用 random.Next(1, 10000) 这样的方法生成随机数。

原文测试用代码片段[改]:


using System;
using System.Linq;
using System.Threading.Tasks; public class Program { public static void Main() {
// This isn't safe, don't do it
Random rng = new Random(); // create a shared Random instance
Parallel.For(0, 10, x => // run in parallel
{
var numbers = new int[10_000];
for (int i = 0; i < numbers.Length; ++i)
{
numbers[i] = rng.Next(); // Fetch 10,000 random numbers, to trigger the thread-safety issues
} var numZeros = numbers.Count(x => x == 0); // how many issues were there?
var avg = numbers.Average();
Console.WriteLine($"Received {numZeros} zeroes avg:{avg} {numbers[0]}");
});
}
}

当然好奇的脚步不止于此,为什么文章说的,大部分人习惯直接调用 .Next() 方法,而不是 .Next(min,max) 这样的方法呢?

我姑且认为是性能问题,于是增加了一个性能测试代码片段,用于生成 (1,100)区间内的随机数:

    public class RandomT
{
System.Random random1 = new System.Random(1);
System.Random random2 = new System.Random(1); System.Random random11 = new System.Random();
System.Random random22 = new System.Random(); [Benchmark]
public int RandomSeedByRange() => random1.Next(1, 100); [Benchmark]
public int RandomSeedByMod() => random2.Next() % 100 + 1; [Benchmark]
public int RandomDefaultByRange() => random11.Next(1, 100); [Benchmark]
public int RandomDefaultByMod() => random22.Next() % 100 + 1;
}

BenchmarkDotNet=v0.13.2, OS=ubuntu 20.04
Intel Xeon Gold 6133 CPU 2.50GHz, 1 CPU, 2 logical and 2 physical cores
.NET SDK=6.0.200
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT AVX2
DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT AVX2
Method Mean Error StdDev
RandomSeedByRange 15.096 ns 0.1449 ns 0.1210 ns
RandomSeedByMod 14.759 ns 0.1298 ns 0.1014 ns
RandomDefaultByRange 9.310 ns 0.0702 ns 0.0548 ns
RandomDefaultByMod 4.925 ns 0.1387 ns 0.2393 ns

性能果然是直接使用 .Next() 最优。两者差距有一倍。

但是,指定随机种子后,两者就没有差距了,这就有点让人想不通了。

.net core 多线程下使用 Random 会出现bug的更多相关文章

  1. 一个实现单线程/多线程下代码调用链中传递数据的处理类: CallContext(LogicalSetData,LogicalGetData),含.net core的实现

    详情请参考原文:一个实现单线程/多线程下代码调用链中传递数据的处理类: CallContext

  2. Vector 是线程安全的,是不是在多线程下操作Vector就可以不用加Synchronized

    如标题一样,如果之前让我回答,我会说,是的,在多线程的环境下操作Vector,不需要加Synchronized. 但是我今天无意间看到一篇文章,我才发现我之前的想法是错误的,这篇文章的地址: http ...

  3. Java进阶专题(十五) 从电商系统角度研究多线程(下)

    前言 ​ 本章节继上章节继续梳理:线程相关的基础理论和工具.多线程程序下的性能调优和电商场景下多线程的使用. 多线程J·U·C ThreadLocal 概念 ​ ThreadLocal类并不是用来解决 ...

  4. 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用

    本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSInvocationOperation.NSOperationQueue的使用,列举几个简单的例子. 默认情况下 ...

  5. python 类变量 在多线程下的共享与释放问题

    最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...

  6. Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask

    CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到 ...

  7. Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger

    前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...

  8. 多线程下C#如何保证线程安全?

    多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题.所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是 ...

  9. 多线程下HashMap的死循环问题

    多线程下[HashMap]的问题: 1.多线程put操作后,get操作导致死循环.2.多线程put非NULL元素后,get操作得到NULL值.3.多线程put操作,导致元素丢失. 本次主要关注[Has ...

  10. ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 349人阅读 评论(0) 收藏

    问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...

随机推荐

  1. (C语言)每日代码||2023.12.25||strcpy()函数两个参数中的'\0'

    #include <stdio.h> #include <string.h> #define MAX 500 void test() { char arr1[] = { '1' ...

  2. SQL中Between And的问题

    使用Between And时需要注意的事项:(1)"between and"是包括边界值的,"not between"不包括边界值.(2)"betwe ...

  3. HDFS文件目录与LiveNodes 数量关系

  4. NC23482 小A的最短路

    题目链接 题目 题目描述 小A这次来到一个景区去旅游,景区里面有N个景点,景点之间有N-1条路径.小A从当前的一个景点移动到下一个景点需要消耗一点的体力值.但是景区里面有两个景点比较特殊,它们之间是可 ...

  5. 使用 .NET 8.0 和 OpenGL 创建一个简易的渲染器

    前言我个人对三维渲染领域的开发有着浓厚的兴趣,尽管并未在相关行业工作过,我的了解还很片面.去年,在与群友聊天时,他们推荐了一本<Unity Shader入门精要>,说适合像我这样想自学的新 ...

  6. Thinkpad笔记本指点杆(小红点)自动漂移的问题

    Dell, HP, Thinkpad在高端商务机上会配备指点杆(小红点), 有很多人是指点杆的忠实用户, 因为工作时可以双手不离键盘, 非常方便. 在指点杆的使用过程中, 有时候会遇到指点杆自己漂移的 ...

  7. STM32F407VET6烧录出现flash download failed target dll has been cancelled

    今天在通过stlink烧录一个长时间未用的STM32F407VET6 Black Board的时候, 出现错误 Internal command error Flash download failed ...

  8. Mysql表读写、索引等操作的sql语句效率优化问题

    上次我们说到mysql的一些sql查询方面的优化,包括查看explain执行计划,分析索引等等.今天我们分享一些 分析mysql表读写.索引等等操作的sql语句. 闲话不多说,直接上代码: 反映表的读 ...

  9. Vuepress + GitHub Actions实现文档博客自动部署

    说明 接着我上一篇文章,已经使用vuepress+github pages搭建好了自己的文档博客,并且可以在本地打包上传后就可以在pages上查看更新内容.但是有1个比较明显的缺点:打包速度并不快!! ...

  10. OCP试题解析之053-16 MEMORY_TARGET

    16.Setting which of the following initialization parameters enables Automatic Memory Management? A. ...