Parallel线程安全问题

废话不多说,上代码:

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。

解决方案很简单:

  1. 加锁
  2. 使用并行集合(System.Collections.ConCurrent)

对于这个问题,我知道其存在潜在的线程安全问题,但是不确定其导致的结果如何?当我截图到处询问无果时,才想到自己动手写demo去验证问题。这也是我写这篇文章的初衷:提醒自己,遇到问题,不要凭空猜测,要有动手验证的决心。

原文地址:https://www.cnblogs.com/sheng-jie/p/8612586.html

时间: 2024-11-08 21:51:35

Parallel线程安全问题的相关文章

java线程安全问题之静态变量、实例变量、局部变量

Java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如:"一个类在可以被多个线程安全调用时就是线程安全的". 此处不赘述了,首先给出静态变量.实例变量.局部变量在多线程环境下的线程安全问题结论,然后用示例验证,请大家擦亮眼睛,有错必究,否则误人子弟! 静态变量:线程非安全. 静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态

多线程创建方式及线程安全问题

1.创建线程方式 一:  创建线程方式一继承Thread类 public clsss MyThread extends Thread{ //重写run方法,设置线程任务 Run(){ } } main(){ new MyThread().start(); } 获取线程名称: Thread.currentThread()获取当前线程对象 Thread.currentThread().getName();获取当前线程对象的名称 二:创建线程方式-实现Runnable接口 创建线程的步骤. 1.定义类

javaweb学习总结二十三(servlet开发之线程安全问题)

一:servlet线程安全问题发生的条件 如果多个客户端访问同一个servlet时,发生线程安全问题,那么它们访问的是相同的资源.如果访问 的不是相同资源,则不存在线程安全问题. 实例1:不会产生线程安全问题,因为每个客户端发送请求,都会创建一个线程,都会创建一个count 不存在资源共享的问题. 1 public void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletExcep

javaweb回顾第六篇谈一谈Servlet线程安全问题

前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例是如何创建,它的模式是什么样的. 在默认的情况下Servlet容器对声明的Servlet,只创建一个Servlet实例,那么如果要是多个客户同时请求访问这个Servlet,Servlet容器就采取多线程.下面我们来看一幅图 从图中可以看出当客户发送请求的时候,Servlet容器通过调度者线程从线程池

servlet线程安全问题

由于默认情况下Servlet,在内存中只有一个实例对象,当多个浏览器并发访问Servlet时就有可能产生线程安全问题 解决方案: 1.加锁--效率降低 synchronized(this){  } 2.SingleThreadModel接口 -- 不能真的防止线程安全问题 在服务器的内部维护一个对象池,放servlet的对象,一个请求过来,会到池里检查一下有没有这个servlet,如果没有,创建一个给当前线程使用,使用完的就放回池里.如果第一个线程使用的servlet对象还没有还回池里,第二线程

servlet/struts1/struts2/spring mvc 的线程安全问题

线程安全的概念: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 线程安全问题都是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全. 在Java里,线程安全一般体现在两个方面:  1.多个thread对同一个java

(2.1)servlet线程安全问题

本文参考链接:http://www.yesky.com/334/1951334.shtml 摘 要:介绍了Servlet多线程机制,通过一个实例并结合Java 的内存模型说明引起Servlet线程不安全的原因,给出了保证Servlet线程安全的三种解决方案,并说明三种方案在实际开发中的取舍. Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率.由于Servlet/JSP默认是以多线程模式执行的,所 以,在编写代码时需要非常细致地考虑多线程的安全性问题.然而,很

浅谈利用同步机制解决Java中的线程安全问题

我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等着前面千百万人挑选购买,最后心仪的商品下架或者售空......假如饿了吗是单线程程序,那么一个用户得等前面全国千万个用户点完之后才能进行点餐,那饿了吗就该倒闭了不是吗?以上两个简单的例子,就说明一个程序能进行多线程并发访问的重要性,今天就让我们去了解一下Java中多线程并发访问这个方向吧. **第一

线程安全问题

/* 需求: 模拟3个窗口同时在售50张 票 . 问题1 :为什么50张票被卖出了150次? 出现 的原因: 因为num是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份. 解决方案:把num票数共享出来给三个线程对象使用.使用static修饰. 问题2: 出现了线程安全问题 ? 线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的. java线程同步机制的方式: 方式一:同步代码块 同步代码块的格式: synchronized(锁对象){