C# 使用ConcurrentBag类处理集合线程安全问题
在日常的开发中,经常会遇到多个线程对同一个集合进行读写操作,就难免会出现线程安全问题。
以下代码,如果使用List<T>就会遇到问题:System.InvalidOperationException:“集合已修改;可能无法执行枚举操作。”。原因是timer2在遍历list的过程当中,timer1修改了list,使其大小发生了变化。所以我们应该使用线程安全的集合来处理。不管是读还是写,同一时刻只能做一件事情,要么读,要么写。
class Program
{
private static List<string> list = new List<string>(); static void Main(string[] args)
{
var count = ; //任务一
Timer timer1 = new Timer((obj) =>
{
var str = "a" + ++count;
list.Add(str);
Console.WriteLine("添加了:" +str);
}, null, , ); //任务二
Timer timer2 = new Timer((obj) =>
{
foreach (var item in list)
{
Console.WriteLine("显示:" + item);
}
}, null, , ); Console.ReadLine();
}
}
改成:ConcurrentBag<T>就不会了,因为ConcurrentBag<T>是线程安全的。
class Program
{
private static ConcurrentBag<string> list = new ConcurrentBag<string>(); static void Main(string[] args)
{
var count = ; //任务一
Timer timer1 = new Timer((obj) =>
{
var str = "a" + ++count;
list.Add(str);
Console.WriteLine("添加了:" +str);
}, null, , ); //任务二
Timer timer2 = new Timer((obj) =>
{
foreach (var item in list)
{
Console.WriteLine("显示:" + item);
}
}, null, , ); //任务三
Timer timer3 = new Timer((obj) =>
{
foreach (var item in list)
{
Console.WriteLine("删除了:" +item);
list.TryTake(out string result);
}
}, null, , ); Console.ReadLine();
}
}
参考网址:https://blog.csdn.net/boonya/article/details/80541460
另外:
如果想在删除时也是线程安全的,也可使用BlockingCollection<T>类。
先把需要删除的找出来,然后再遍历删除
foreach (var id in ids)
{
var hub = _hubs.FirstOrDefault(m => m.Id == id);
if (hub != null)
{
_hubs.TryTake(out hub);
}
}
private BlockingCollection<HubModel> _hubs;
C# 使用ConcurrentBag类处理集合线程安全问题的更多相关文章
- JUC之集合中的线程安全问题
集合线程安全问题 JDK Version:9 首先说下集合线程安全是什么:当多个线程对同一个集合进行添加和查询的时候,出现异常错误. 复现例子: package com.JUC; import jav ...
- SimpleDateFormat类的线程安全问题和解决方案
摘要:我们就一起看下在高并发下SimpleDateFormat类为何会出现安全问题,以及如何解决SimpleDateFormat类的安全问题. 本文分享自华为云社区<SimpleDateForm ...
- 零基础学习java------day18------properties集合,多线程(线程和进程,多线程的实现,线程中的方法,线程的声明周期,线程安全问题,wait/notify.notifyAll,死锁,线程池),
1.Properties集合 1.1 概述: Properties类表示了一个持久的属性集.Properties可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串 一个属性列表可包含另 ...
- Java中各种集合(字符串类)的线程安全性!!!
Java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...
- 08 Java 集合的线程安全问题
1 Java中的集合 Java中的集合分为同步的集合(线程安全)和线程不安全的集合 例如 : ArrayList和Vector的区别: 一.同步性:Vector是线程安全的,也就是说是同步的,而Arr ...
- Java日期时间API系列4-----Jdk7及以前的日期时间类的线程安全问题
1.Date类为可变的,在多线程并发环境中会有线程安全问题. (1)可以使用锁来处理并发问题. (2)使用JDK8 Instant 或 LocalDateTime替代. 2.Calendar的子类为 ...
- Java之同步方法处理继承Thread类的线程安全问题
/** * 使用同步方法处理继承Thread类的方式中的线程安全问题 * */class Window4 extends Thread { private static int ticket = 10 ...
- Java之同步代码块处理继承Thread类的线程安全问题
package com.atguigu.java; /** *//** * 使用同步代码块解决继承Thread类的方式的线程安全问题 * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thre ...
- Java静态static工具类线程安全问题研究
针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...
随机推荐
- WPF ItemsSource Order by Getter
public ObservableCollection<CustomerModel> CustomerCollection { get { if(customerCollection!=n ...
- pyqt5学习
详细设计追函数报告生成 界面大致如下: 部分UI代码: #!/usr/bin/env python3.7 # -*- coding:utf-8 -*- # Author: Lancer 2019-09 ...
- .NET开发框架(六)-架构设计之IIS负载均衡(视频)
前面有关注我们公众号文章的朋友应该都知道,我们的分布式应用服务可以通过Ocelot网关进行负载均衡,这种方式属于应用级别的实现. 而今天我们给大家介绍的是平台级别的实现,并且我们首次使用视频方式进行讲 ...
- NBIOT实现UDP协议的发送和接收(包含软件升级)
源码下载: nbiot_module程序(java netbean) -> 提取码 UdpServer程序(C# vs2010) -> 提取码 QQ:505645074 前提条件:开NB卡 ...
- H3C路由器设置NAT回环、端口回流
起因 当用本地服务器作为frp的服务端时,需要在路由器上设置端口映射,将公网ip和本地ip映射起来,用于作为frps的公网,这一步很简单一般都会有可视化界面来实现,但实际测试时发现问题: 当非局域网内 ...
- TP5 Request 请求对象【转】
app\index\controller\Index.php <?php namespace app\index\controller; use think\Request; class Ind ...
- os模块,sys模块,json和pickle模块,logging模块
目录 OS模块 sys模块 json和pickle模块 序列化和反序列化 json模块 pickle logging模块 OS模块 能与操作系统交互,控制文件 / 文件夹 # 创建文件夹 import ...
- 【Spring Boot】Spring Boot之使用ImportBeanDefinitionRegistrar类实现动态注册Bean
一.ImportBeanDefinitionRegistrar类介绍 ImportBeanDefinitionRegistrar类通过其他@Configuration类通过@Import的方式来加载, ...
- 6. [mmc subsystem] mmc core(第六章)——mmc core主模块
一.说明 1.mmc core概述 mmc core主模块是mmc core的实现核心.也是本章的重点内容. 对应代码位置drivers/mmc/core/core.c. 其主要负责如下功能: mmc ...
- java stream 集合运算
1.对列表进行分组,构建成一个map对象. 键为用户名称,值为用户对象列表. Person p1 = new Person("张三", new BigDecimal("1 ...