在日常的开发中,经常会遇到多个线程对同一个集合进行读写操作,就难免会出现线程安全问题。

以下代码,如果使用List<T>就会遇到问题:System.InvalidOperationException:“集合已修改;可能无法执行枚举操作。”。原因是timer2在遍历list的过程当中,timer1修改了list,使其大小发生了变化。所以我们应该使用线程安全的集合来处理。不管是读还是写,同一时刻只能做一件事情,要么读,要么写。

  1. class Program
  2. {
  3. private static List<string> list = new List<string>();
  4.  
  5. static void Main(string[] args)
  6. {
  7. var count = ;
  8.  
  9. //任务一
  10. Timer timer1 = new Timer((obj) =>
  11. {
  12. var str = "a" + ++count;
  13. list.Add(str);
  14. Console.WriteLine("添加了:" +str);
  15. }, null, , );
  16.  
  17. //任务二
  18. Timer timer2 = new Timer((obj) =>
  19. {
  20. foreach (var item in list)
  21. {
  22. Console.WriteLine("显示:" + item);
  23. }
  24. }, null, , );
  25.  
  26. Console.ReadLine();
  27. }
  28. }

改成:ConcurrentBag<T>就不会了,因为ConcurrentBag<T>是线程安全的。

  1. class Program
  2. {
  3. private static ConcurrentBag<string> list = new ConcurrentBag<string>();
  4.  
  5. static void Main(string[] args)
  6. {
  7. var count = ;
  8.  
  9. //任务一
  10. Timer timer1 = new Timer((obj) =>
  11. {
  12. var str = "a" + ++count;
  13. list.Add(str);
  14. Console.WriteLine("添加了:" +str);
  15. }, null, , );
  16.  
  17. //任务二
  18. Timer timer2 = new Timer((obj) =>
  19. {
  20. foreach (var item in list)
  21. {
  22. Console.WriteLine("显示:" + item);
  23. }
  24. }, null, , );
  25.  
  26. //任务三
  27. Timer timer3 = new Timer((obj) =>
  28. {
  29. foreach (var item in list)
  30. {
  31. Console.WriteLine("删除了:" +item);
  32. list.TryTake(out string result);
  33. }
  34. }, null, , );
  35.  
  36. Console.ReadLine();
  37. }
  38. }

参考网址:https://blog.csdn.net/boonya/article/details/80541460

另外:

如果想在删除时也是线程安全的,也可使用BlockingCollection<T>类。

先把需要删除的找出来,然后再遍历删除

  1. foreach (var id in ids)
  2. {
  3. var hub = _hubs.FirstOrDefault(m => m.Id == id);
  4. if (hub != null)
  5. {
  6. _hubs.TryTake(out hub);
  7. }
  8. }
  1. private BlockingCollection<HubModel> _hubs;

C# 使用ConcurrentBag类处理集合线程安全问题的更多相关文章

  1. JUC之集合中的线程安全问题

    集合线程安全问题 JDK Version:9 首先说下集合线程安全是什么:当多个线程对同一个集合进行添加和查询的时候,出现异常错误. 复现例子: package com.JUC; import jav ...

  2. SimpleDateFormat类的线程安全问题和解决方案

    摘要:我们就一起看下在高并发下SimpleDateFormat类为何会出现安全问题,以及如何解决SimpleDateFormat类的安全问题. 本文分享自华为云社区<SimpleDateForm ...

  3. 零基础学习java------day18------properties集合,多线程(线程和进程,多线程的实现,线程中的方法,线程的声明周期,线程安全问题,wait/notify.notifyAll,死锁,线程池),

    1.Properties集合 1.1 概述: Properties类表示了一个持久的属性集.Properties可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串 一个属性列表可包含另 ...

  4. Java中各种集合(字符串类)的线程安全性!!!

    Java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...

  5. 08 Java 集合的线程安全问题

    1 Java中的集合 Java中的集合分为同步的集合(线程安全)和线程不安全的集合 例如 : ArrayList和Vector的区别: 一.同步性:Vector是线程安全的,也就是说是同步的,而Arr ...

  6. Java日期时间API系列4-----Jdk7及以前的日期时间类的线程安全问题

    1.Date类为可变的,在多线程并发环境中会有线程安全问题. (1)可以使用锁来处理并发问题. (2)使用JDK8  Instant 或 LocalDateTime替代. 2.Calendar的子类为 ...

  7. Java之同步方法处理继承Thread类的线程安全问题

    /** * 使用同步方法处理继承Thread类的方式中的线程安全问题 * */class Window4 extends Thread { private static int ticket = 10 ...

  8. Java之同步代码块处理继承Thread类的线程安全问题

    package com.atguigu.java; /** *//** * 使用同步代码块解决继承Thread类的方式的线程安全问题 * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thre ...

  9. Java静态static工具类线程安全问题研究

    针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...

随机推荐

  1. java架构之路(多线程)JMM和volatile关键字

    说到JMM大家一定很陌生,被我们所熟知的一定是jvm虚拟机,而我们今天讲的JMM和JVM虚拟机没有半毛钱关系,千万不要把JMM的任何事情联想到JVM,把JMM当做一个完全新的事物去理解和认识. 我们先 ...

  2. 时间复杂度o(1), o(n), o(logn), o(nlogn)

    1.时间复杂度o(1), o(n), o(logn), o(nlogn).算法时间复杂度的时候有说o(1), o(n), o(logn), o(nlogn),这是算法的时空复杂度的表示.不仅仅用于表示 ...

  3. sqlserver the name is not a valid identifier error in function

    参考资料:https://stackoverflow.com/questions/22008859/the-name-is-not-a-valid-identifier-error-in-functi ...

  4. rsync性能终极优化【Optimize rsync performance】

    前言 将文件从一台计算机同步或备份到另一台计算机的快速简便的方法是使用rsync.我将介绍通常用于备份数据的命令行选项,并显示一些选项以极大地将传输速度从大约20-25 MB / s加快到90 MB ...

  5. Python中的常见特殊方法—— del方法

    __del__() 方法用于销毁Python对象——在任何Python对象将被系统回收的时候,系统都会自动调用这个方法.但是不要以为对一个变量执行del操作,该变量引用的对象就会被回收,当然不是,如果 ...

  6. elasticsearch bulk

    情景介绍 公司2000W的数据从mysql 迁移至elasticsearch,以提供微服务.本文基于elasticsearch-py bulk操作实现数据迁移.相比于elasticsearch-dum ...

  7. day 34 作业

    作业 mysql> create table tea( -> id int unsigned auto_increment primary key, -> name varchar( ...

  8. nginx Linux内核参数的优化

    默认的Linux内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改Linux内核参数,使得Nginx可以拥有更高的性能. 这里针对最通用的.使Nginx支持 ...

  9. Linux 用libevent实现的简单http服务器

    Linux 用libevent实现的简单http服务器 main.c #include <stdio.h> #include <sys/types.h> #include &l ...

  10. my.cnf配置文件实用优化

    [client] 1.登陆过程自动化(这样做可以让你在命令行登陆的时候免去输入用户名和密码) host="mysql服务器地址" user="用户名" pass ...