为什么 Random.Shared 是线程安全的

在多线程环境中使用 Random 类来生成伪随机数时,很容易出现线程安全问题。例如,当多个线程同时调用 Next 方法时,可能会出现种子被意外修改的情况,导致生成的伪随机数不符合预期。

为了避免这种情况,.NET 框架引入了 Random.Shared 属性。它返回一个特殊的 Random 实例,可以在多线程环境中安全地生成伪随机数。

代码示例

下面是一个示例代码,演示了 Random.Shared 属性的使用方法:

using System;
using System.Threading;
using System.Threading.Tasks;namespace MyApp
{public class Program{public static void Main(string[] args){// 使用 Random.Shared 属性创建一个新的 Random 实例var random = Random.Shared;// 创建两个新的 Task,分别用于生成伪随机数var task1 = Task.Run(() =>{// 生成伪随机数for (int i = 0; i < 5; i++){// 调用 Next 方法生成伪随机数var number = random.Next();// 输出当前线程的编号和生成的伪随机数Console.WriteLine($"Thread1: {Thread.CurrentThread.ManagedThreadId}, number = {number}");// 模拟耗时操作Thread.Sleep(500);}});var task2 = Task.Run(() =>{// 生成伪随机数for (int i = 0; i < 5; i++){// 调用 Next 方法生成伪随机数var number = random.Next();// 输出当前线程的编号和生成的伪随机数Console.WriteLine($"Thread2: {Thread.CurrentThread.ManagedThreadId}, number = {number}");// 模拟耗时操作Thread.Sleep(500);}});// 等待两个 Task 完成Task.WaitAll(task1, task2);// 等待用户输入Console.ReadKey();}}
}

在上面的代码中,我们使用 Random.Shared 属性创建了一个新的 Random 实例,然后在两个不同的线程中分别调用它的 Next 方法生成伪随机数。由于 Random.Shared 属性是线程安全的,所以两个线程之间的访问不会发生冲突,可以正常生成伪随机数。

原理说明

Random.Shared 属性返回的 Random 实例内部实际上使用了 [ThreadStatic] 属性,来实现对种子的线程安全访问。

[ThreadStatic] 属性用于标识一个字段,表示该字段在每个线程中都有一个独立的值。例如,如果一个字段被标记为 [ThreadStatic],那么每个线程都会有一个单独的副本,它们之间互不影响。

举个例子,假设我们有一个类,它有一个 [ThreadStatic] 字段:

public class MyClass
{[ThreadStatic]public static int Counter;
}

在这个例子中,Counter 字段被标记为 [ThreadStatic],表示每个线程都有一个单独的副本。例如,当我们在两个不同的线程中访问 Counter 字段时,实际上访问的是两个不同的副本,它们之间互不影响。

下面是一个示例代码,演示了 [ThreadStatic] 属性的使用方法:

using System;
using System.Threading;
using System.Threading.Tasks;namespace MyApp
{public class Program{public static void Main(string[] args){// 创建两个新的 Task,分别用于访问 Counter 字段var task1 = Task.Run(() =>{// 访问 Counter 字段for (int i = 0; i < 5; i++){// 增加 Counter 的值MyClass.Counter++;// 输出当前线程的编号和 Counter 的值Console.WriteLine($"Thread1: {Thread.CurrentThread.ManagedThreadId}, Counter = {MyClass.Counter}");// 模拟耗时操作Thread.Sleep(500);}});var task2 = Task.Run(() =>{// 访问 Counter 字段for (int i = 0; i < 5; i++){// 增加 Counter 的值MyClass.Counter++;// 输出当前线程的编号和 Counter 的值Console.WriteLine($"Thread2: {Thread.CurrentThread.ManagedThreadId}, Counter = {MyClass.Counter}");// 模拟耗时操作Thread.Sleep(500);}});// 等待两个 Task 完成Task.WaitAll(task1, task2);// 等待用户输入Console.ReadKey();}}
}

在上面的代码中,我们创建了两个新的 Task,分别用于访问 Counter 字段。由于 Counter 字段被标记为 [ThreadStatic],所以两个 Task 在不同的线程中执行,访问的是两个不同的副本。我们可以从输出结果看出,两个 Task 之间的修改不会影响到对方。

运行上面的代码可能会得到类似下面的样例结果:

Thread1: Counter = 1
Thread1: Counter = 2
Thread1: Counter = 3
Thread1: Counter = 4
Thread1: Counter = 5
Thread2: Counter = 1
Thread2: Counter = 2
Thread2: Counter = 3
Thread2: Counter = 4
Thread2: Counter = 5

可以看到,每个线程都会使用自己的 _counter 变量来记录递增的值,因此两个线程之间的值是不同的。

以上是 [ThreadStatic] 属性的使用方法。在 Random.Shared 属性的实现中,也采用了类似的方法,来实现种子的线程安全访问。由于每个线程都有一个单独的种子,所以它们之间互不影响,并且也不会发生线程安全问题。

使用建议

在多线程环境中,我们建议使用 Random.Shared 属性来生成伪随机数。它能够提供线程安全的保证,避免出现种子被意外修改的情况。

总结

通过使用 [ThreadStatic] 属性,.NET 框架实现了线程安全的 Random.Shared 属性。它允许我们在多线程环境中安全地生成伪随机数,而不用担心种子被意外修改的情况。

参考资料:

  • ThreadStaticAttribute Class

  • Random.Shared Property

本文采用 Chat OpenAI 辅助注水浇筑而成,如有雷同,完全有可能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(3)Python3笔记之变量与运算符

一、变量 1&#xff09;. 命名规则&#xff1a; 1. 变量名不能使用系统关键字或保留关键字 2. 变量区分大小写 3. 变量命名由字母&#xff0c;数字&#xff0c;下划线组成但不能以数字开头 4. 不需要声明变量类型 是 a 1 非 int a 1 5. 查看变量内存地址 id(a), id(b) 6…

some demos

import ../css/detail.css;// 找到字符串中重复次数最多的字符 function findMax(str) {let maxChar ;let maxValue 1;if (!str.length) return;let arr str.replace(/\s/g, ).split();let obj {};for (let i 0; i < arr.length; i) {if (!obj[arr[i]]) {obj[arr[i]] …

WPF 实现视频会议与会人员动态布局

WPF 实现视频会议与会人员动态布局控件名&#xff1a;SixGridView作 者&#xff1a;WPFDevelopersOrg - 驚鏵原文链接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40&#xff1b;Visual Studio 2019;接着上一篇是基于Grid实现的视频查看感…

汉三水属国(北地属国、安定属国)

汉三水属国&#xff08;北地属国、安定属国&#xff09; 两汉&#xff08;西汉、东汉&#xff09;400年中&#xff0c;由于各种原因&#xff0c;经常有成批的匈奴归附汉朝&#xff0c;两汉政府对他们采取了较为妥善的安置政策&#xff0c;其中最主要的措施是为他们设立专门的居…

《爆发》作者:大数据领域将有新赢家

本文讲的是《爆发》作者&#xff1a;大数据领域将有新赢家,全球复杂网络研究专家日前到访中国&#xff0c;为其新作《爆发》作宣传。他在接受国内媒体采访时表示&#xff0c;未来可能有新公司取代谷歌、Facebook等公司&#xff0c;成为大数据领域的赢家。 《爆发》一书是一本讨…

chromebook刷机_如何获取Android应用以查看Chromebook上的外部存储

chromebook刷机Android apps are a great way to expand the sometimes limited capabilities of Chromebooks, but they can be a problem if you store most of your data on an external medium—like an SD card, for example. Android应用程序是扩展Chromebook有时有限功能…

Stream流与Lambda表达式(四) 自定义收集器

一、自定义SetCustomCollector收集器 package com.java.design.Stream.CustomCollector;import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; im…

ModelState.IsValid忽略型别的检查错误

Web Api在Int或DateTime如果传空值的话会自动帮忙设预设值&#xff0c;但是在ModelState.IsValid的时候&#xff0c;却会出现型别上的错误.解决方式把Model改成正确&#xff0c;也就是预设允许可以为nullpublic class DemoModel { …

android 指纹添加_如何将手势添加到Android手机的指纹扫描仪

android 指纹添加So you have a shiny new Android phone, equipped with a security-friendly fingerprint scanner. Congratulations! But did you know that, while useful on its own, you can actually make the fingerprint scanner do more than just unlock your phone…

关于前端性能优化

常用的优化有两部分 第一&#xff1a;面向内容的优化 减少 HTTP 请求减少 DNS 查找避免重定向使用 Ajax 缓存延迟载入组件预先载入组件减少 DOM 元素数量切分组件到多个域最小化 iframe 的数量不要出现http 404 错误第二&#xff1a;面向 Server 缩小 Cookie针对 Web 组件使用域…

前端工程化:围绕Jenkins打造工作流的过程

背景 1年前入职时&#xff0c;公司前端部门的静态代码部署都是用ftp工具拖拽部署&#xff0c;没有记录&#xff0c;没有关联&#xff0c;经常造成许多困扰的问题&#xff0c; 比如&#xff1a;今天有没有其他人在我要部署的路径上工作&#xff1f;我的代码为啥被盖掉了&#xf…

业务id转密文短链的一种实现思路

业务场景&#xff1a; 买家通过电商app下单后&#xff0c;会受到一条短信&#xff0c;短信内容中包括改订单详情页面的h5地址连接&#xff0c;因为是出现在短信中&#xff0c;所以对连接有要求&#xff1a;1.尽量短&#xff1b;2.安全性考虑&#xff0c;订单在数据库中对应的自…

百度高管:问心无愧

1月23日下午消息&#xff0c;今天下午&#xff0c;百度召开百家号2019内容创作者盛典&#xff0c;百度副总裁沈抖出席并发布演讲。 就在前一天&#xff0c;一篇名为《搜索引擎百度已死》的文章刷屏&#xff0c;文中提到百度搜索有一半以上会指向百度自家产品&#xff0c;尤其百…

Vuex 学习笔记

Vuex 是什么&#xff1f; Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。由于SPA应用的模块化&#xff0c;每个组件都有它各自的数据&#xff08;state&#xff09;、视图&#xff08;view&#xff09;和方法&#xff08;actions&#xff09;&#xff0c;当项目内容越来越…

xdf文档怎么转换为pdf_如何将PDF文件和图像转换为Google文档文档

xdf文档怎么转换为pdfYou probably know you can create and edit documents with Google Docs, but you can edit more than just .doc files. Google Drive can also convert any PDF, JPG, PNG, or GIF into a document with fully editable text. Here’s how. 您可能知道可…

在现代 Windows 上使用经典 Windows 2000、XP、Vista 任务栏

你好&#xff0c;这里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;实用的工具和组件&#xff0c;希望对您有用&#xff01;前言您第一次使用的 Windows 是哪个版本的&#xff1f;我最早使用的 Windows XP&#xff0c;然后再经过 XP、7、8/8.1 、Windows 10&a…

oracle sys可以登录,system权限不足,解决方法

今天在自己电脑上安装了oracle 11g&#xff0c;安装成功后发现 sys 可以正常登录。system 无法登录&#xff0c;显示 ORA-01031: insufficient privileges(权限不足) select * from v$pwfile_users; 查看有sysdba权限的用户 grant sysdba to system; 给system 授权sysdba权限…

airdroid黑屏_如何使用AirDroid从PC控制Android设备

airdroid黑屏AirDroid for Android replaces your USB cable for connecting to your PC. Transfer files back and forth, send text messages, play music, view your photos, and manage applications using a web browser or a desktop client. 适用于Android的AirDroid取代…

分析java程序

2019独角兽企业重金招聘Python工程师标准>>> 最近公司的一个账单推送的服务&#xff0c;发现有延迟。我排查的时候发现&#xff0c;有一个程序日志不动了&#xff08;采用消息队列&#xff0c;部署了两台服务器来负载均衡&#xff09;。 网上说&#xff1a; jstack …