Parallel线程安全问题
2023-02-18 16:47:14 时间
废话不多说,上代码:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ParallelTest
{
class Program
{
static void Main(string[] args)
{
List<Product> products = new List<Product>();
Parallel.For(0, 1000000, (i) =>
{
Product product = new Product();
product.Name = "name" + i;
product.Category = "Category" + i;
product.SellPrice = i;
products.Add(product);
});
Console.WriteLine(products.Count);
Console.ReadLine();
}
}
class Product
{
public string Name { get; set; }
public string Category { get; set; }
public int SellPrice { get; set; }
}
}
猜一下,运行结果是多少,是999999?抱歉不是的,结果!= 999999。
Net 4.0引入了System.Threading.Tasks,简化了我们进行异步编程的方式,而不用直接与线程和线程池打交道,但这也引入了线程安全问题。
System.Threading.Tasks中的类型被称为任务并行库(TPL)。TPL使用CLR线程池(说明使用TPL创建的线程都是后台线程)自动将应用程序的工作动态分配到可用的CPU中。
其中Parallel是指数据并行,其提供的Parallel.For()或Parallel.ForEach()方法,可以以并行方式对数组或集合中的数据进行迭代。
那之所以出现这个结果,很显然了,是多线程操作集合导致的线程安全问题。
总之,多线程操作集合时一定要注意线程安全的问题,不管是通过Thread、ThreadPool、Task、Parallel还是PLINQ。
解决方案很简单:
- 加锁
- 使用并行集合(System.Collections.ConCurrent)
对于这个问题,我知道其存在潜在的线程安全问题,但是不确定其导致的结果如何?当我截图到处询问无果时,才想到自己动手写demo去验证问题。这也是我写这篇文章的初衷:提醒自己,遇到问题,不要凭空猜测,要有动手验证的决心。
相关文章
- redis系列之初识Redis
- Redis系列之如何高效使用
- NLP: Text Neural Network (Part1: textRNN, textCNN)
- [NetWork] 局域网基本原理
- Redis实现朋友圈,微博等Feed流功能,实现Feed流微服务(代码实现)
- 下载速率提升40% ,《斗罗大陆:魂师对决》是如何做到的?
- 华为Awareness kit,您旅途路上的超智能管家
- Discovery直播 | 移动应用“通行证”——钥匙环,解锁管家式安全出行服务
- 教你在“狼人杀”中实现变声效果
- 技术与艺术的结合,HMS Core让手机主题趣味丛生
- 受众同步管理功能上线,让你的活动礼包发对人
- 分析服务助力产品运营
- 租房买房行业报告上线,为房产服务数字化转型添砖加瓦
- 放码来战!HMS Core线上Codelabs挑战赛正式开始
- 一图读懂DCI版权服务
- 【HMS Core 6.0全球上线】Toolkit,您的智能辅助编程好帮手
- 眼镜选款新方法,用AR+Scene技术实现3D虚拟试戴
- HDD成都站:HMS Core 6.0带来新可能,多元服务驱动产品价值提升
- Insights直播预告 | 多媒体管线服务,助您轻松进入“技术流”创新阵地
- 华为音频编辑服务带你一键伴奏分离!