学习
实践
活动
工具
TVP
写文章

C#线程List线程安全问题

网上关于List线程安全问题将的很少,所以自己实验了一把,发现确实是线程安全的.所以当你在进行多线程编程中使用了共享的List集合,必须对其进行线程安全处理. List的Add方法是线程安全的,List的源码中的Add方法,使用了每次当当前的元素达到上限,通过创建一个新的数组实例,并给长度翻倍的操作.如果单线程操作不会有问题,直接扩容,然后继续往里面加值。 也就是说,当多个线程同时添加元素,且刚好它们都执行到了扩容这个阶段,当一个线程扩大了这个数组的长度,且进行了+1操作后,另外一个线程刚好也在执行扩容的操作,这个时候它给Capacity的值设为2048, 但是另外一个线程已经将this. (i); } } } } ok,解决了问题,当然这不是最好的解决方案,你完全可以通过适配器模式,去扩展一个线程安全List

1.9K50

C# 线程安全线程同步技术

线程安全线程同步技术概念: 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。 线程同步技术:是指多线程程序中,为了保证后者线程,只有等待前者线程完成之后才能继续执行。就好比买票,前面的人没买到票之前,后面的人必须等待。所谓同步:是指在某一时刻只有一个线程可以访问变量。 c#为同步访问变量提供了一个非常简单的方式,即使用c#语言的关键字Lock,它可以把一段代码定义为互斥段,互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。 在c#中,关键字Lock定义如下: Lock(expression) { statement_block } expression代表你希望跟踪的对象。 lock 是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的。可以看到这种方式的确没有阻塞主线程,而且成员变量的值也是连续递增的,说明是线程安全的。

1K10
  • 广告
    关闭

    热门业务场景教学

    个人网站、项目部署、开发环境、游戏服务器、图床、渲染训练等免费搭建教程,多款云服务器20元起。

  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C#线程安全使用(二)

    刚才想了半天文章应该起什么名字,最后决定起名为《线程安全使用》,线程安全这个词很难理解,感觉就像托管这词一样,但是托管翻译成英文是managed,我通常把他翻译成被管理,这样就好理解多了,线程安全也是一样 ,可以理解为可以被多个线程同时使用的集合,而且同时使用的时候是该集合的值是准确的。 MSDN将在System.Collections.Concurrent命名空间下的集合,都称为线程安全的集合。 下面举一个使用线程安全集合的例子,使用的是BlockingCollection,个人觉得这个集合是够用了,其他集合和这个集合基本上大同小异,没什么大区别。 task.RunSynchronously(),根据MSDN解释,他是同步运行任务计划用的,同时他和task.Start()一样,也可以启动线程

    45830

    C#线程安全使用(五)

    CancellationToken的多种应用 这是线程安全的最后一篇了,主要介绍CancellationToken的多种应用。 1,ThreadPool直接启动线程,传递CancellationToken。 2,Task启动线程,传递CancellationToken。 到此NET Framework4.0里的线程安全就都讲完了。。。。。。。 虽然第一篇文章是2013年,虽然历时近五年,但请相信我,代码早在五年前就已经写完啦。 不然这线程安全的文章可能还要拖。。。。。。。。 哈哈  后记 在NET Framework4.6里,微软提供了async和await语法,也是有关线程安全,我将会在新的语法相关文章里讲解async和await的用法。

    35520

    C#线程安全使用(一)

    TaskConsole { class Program { static void Main(string[] args) { //当前线程标识 ation)中task的任务 Console.WriteLine("任务标识:" + task.GetHashCode() + ",状态:" + task.Status + ",当前线程

    1K30

    C#线程安全使用(三)

    线程11后是线程12,然后是13,14,11等。 每个线程都是等到执行完了下一个才执行。 ? 在看一下没有Lock的结果,如下图,线程是混乱的,12线程的函数没执行完13就开始了。 ? 有了上面的例子,Lock就很好理解了,他是为了保障资源同一时间只被一个线程使用,虽然该例子中没有使用Lock的资源,但线程还是一个接一个的执行,因为使用了lock线程就会一个接一个执行。 的值,当usingResource等于0的时候,当前线程不运行,否则运行,当本线程运行时,要修改usingResource的值为1,这样确保其他线程不运行,即同一时间只运行一个线程。 如果这样需求用到开发中,会出现一个问题,那就是当一个线程改变usingResource的值的一瞬间,别的线程读取了usingResource的值,那这个线程也被运行了。

    69821

    C#线程安全使用(四)

    这里主要讲解下CancellationTokenSource,CancellationTokenSource是用于取消线程,具体使用起来有点另类:首先定义实体,然后将其下的属性ToKen传递给线程,当需要取消线程时 ,如果随即数等于0就取消该线程。   token = source.Token; Random rnd = new Random(); Object lockObj = new Object(); List <Task<int[]>> tasks = new List<Task<int[]>>(); TaskFactory factory = new TaskFactory(token); ,即当线程2中调用Cancel后,其他线程也被取消了。

    28730

    C# 并发安全集合ConcurrentBag取代List

    List集合是非线程安全的,所以我们这里了解下安全集合ConcurrentBag。 namespace MyConcurrent { class Program { ///

    /// ConcurrentBag并发安全集合 summary> public static void ConcurrentBagWithPallel() { ConcurrentBag<int> list (item); }); Console.WriteLine("ConcurrentBag's count is {0}", list.Count()); int n = 0; foreach (int i in list) { if (n > 10)

    2K10

    C# Int 类型线程安全

    但是发现并行后丢居然数据(当然是因为List线程安全)。 前几天写了一个demo如下,发现如果MAX很大时,count小于MAX,Int 居然是线程安全的,即便是Int++; int count = 0; int MAX =

    57020

    C# list介绍

    泛型的好处: 它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到提高。 二、性能注意事项: 在决定使用IList<T> 还是使用ArrayList类(两者具有类似的功能)时,记住IList<T> 类在大多数情况下执行得更好并且是类型安全的。 三、一般用法 1、 List的基础、常用方法: 声明: 1、List<T> mList = new List<T>(); T为列表中元素类型,现在以string类型作为例子 E.g.: List Locu” }; List<string> testList = new List<string>(temArr); 添加元素: 1、 List. .: mList.Sort(); List清空:List. Clear () E.g.: mList.Clear(); 获得List中元素数目: List.

    8010

    C# List用法 List 实列介绍

    using System; using System.Collections.Generic; namespace List { class Program { static “李四”, 20); Person p3 = new Person(“王五”, 50); //创建类型为Person的对象集合 List <Person> persons = new List<Person>(); //将Person对象放入集合 persons.Add(p1);

    8210

    c#线程-线程同步

    线程同步 如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏。如果多个线程不会同时访问共享数据,可以不用线程同步。 线程同步也会有一些问题存在: 1、性能损耗。 线程同步的几种方法 阻塞 当线程调用Sleep,Join,EndInvoke,线程就处于阻塞状态(Sleep使调用线程阻塞,Join、EndInvoke使另外一个线程阻塞),会立即从cpu退出。 locker2) //共享数据的操作,非静态方法,是用非静态锁,确保同一个实例的方法调用者排队执行 } } 同步对象可以兼作它lock的对象 如: class ThreadSafe { private List _list = new List (); void Test() { lock (_list) { _list.Add (“Item 1”); } } } Monitors lock其实是 //线程:2 写操作2017/7/5 17:50:02 //线程:2写结束... //屏蔽writer方法 //线程:3准备读... //线程:5准备读... //线程:4准备读...

    17030

    c# List去重

    需求 : 对List集合中的元素去重。 =lst1.Distinct().ToList(); 使用hashset public static List<T> RemoveT<T>(List<T> items) { <string> ForLoopRemove(List<string> items) { List<string> output = new List< List<Student> lst = new List<Student>(); lst.Add(new Student { No = 23, name = "李磊" <string> ForLoopRemove(List<string> items) { List<string> output = new List<

    12820

    C#——list列表复制

    #声明和实例化 声明:ArrayList a, 仅仅只是声明了一个list变量,其未来作用相当于C++中的引用变量,亦或者相当于一个对象块的索引,但并未为其分配具体的完整的对象所需要的内存空间,其所分配的空间仅仅只是 此时,对象a才是该list的一个实例,然后将分配的内存地址返回给定义的变量“a”; #java的实例化 1. 使用new关键词创建对象(c++)。 2.通过jdk中提供的工厂方法返回对象。 #结合背景知识,给出List赋值给另一个List的相关问题 1.

    96541

    c# list操作实例

    ConsoleApplication6 { class Program { static void Main(string[] args) { List <string[]> str1 = new List<string[]> { }; List<string[]> str2 = new List<string[]> { }; <string> lists = new List<string> { }; lists.Add("str"); lists.Add("hello"); <byte[]> byt1 = new List<byte[]> { }; List<byte[]> byt2 = new List<byte[]> { }; List<byte> byt3 = new List<byte> { }; byte[] by1 = { 0x11, 0x03, 0x05 ,0x24};

    42920

    C#线程

    在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。   在 C# 中,System.Threading.Thread 类用于线程的工作。 创建线程 ----   当 C# 程序开始执行时,主线程自动创建。使用 Thread 类创建的线程被主线程的子线程调用。通过Start()方法来启动线程。 控制线程 ----   C#的Thread类为我们提供了几个重要的方法来控制线程:   Start():启动线程;   Sleep(int):静态方法,暂停当前线程指定的毫秒数;   Abort():通常使用该方法来终止一个线程C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal lock是C#中最常用的同步方式,格式为:lock(objectA){codeB} 。

    50050

    C# dotnet 线程安全的弱引用缓存

    本文给大家一个弱引用缓存,也就是在频繁使用时从内存获取,在不使用时会被回收,这样可以提升性能也能减少内存使用 因为作为缓存,如果需要考虑线程安全,那么这部分的逻辑就复杂了。 在不考虑线程安全下,开发一个弱引用缓存还是很简单 首先是创建一个字典,这个字典包含弱引用,这样在获取之前可以先从字典获取 private readonly Dictionary<object { var type = typeof(T); return GetOrCreate(type, createFunc); } 这个线程安全的弱引用缓存所有代码很少 WeakReference<object>> _cacheList = new Dictionary<object, WeakReference<object>>(); } 此方法是线程安全的 ,请不要在多线程下使用此方法,可以通过 线程静态字段 让一个线程有一个实例 本文代码放在 github 欢迎小伙伴访问

    8820

    dotnet C# 给结构体字段赋值非线程安全

    在 dotnet 运行时中,给引用对象进行赋值替换的时候,是线程安全的。给结构体对象赋值,如果此结构体是某个类的成员字段,那么此赋值不一定是线程安全的。 是否线程安全,取决于结构体的大小,取决于此结构体能否在一次原子赋值内完成 大家都知道,某个执行逻辑如果是原子逻辑,那么此逻辑是线程安全的。 满足于此即可称为线程安全,因为线程不会读取到中间状态。 ,因此放在栈上的结构体在线程上是独立的,相互之间没有影响,也就是线程安全的 如果是放在堆上面的结构体,如作为某个类对象的字段,此时的结构体将会占用此类对象的内存空间,如对以下代码的内存示意图 class Program { static void Main(string[] args) { var taskList = new List<Task

    16230

    线程---线程安全

    线程安全是开发者在开发多线程任务时最关心的问题,那么线程安全需要注意哪些呢? 一、思考:线程安全产生的原因是什么? 二、final,volatile关键字的作用? 四、如何编写线程安全的程序? 五、ThreadLocal使用的注意事项有哪些? 一、思考:线程安全产生的原因是什么? 二、如何实现线程安全呢? 根据线程安全原因:可变资源(内存)线程间共享可得出: 不共享资源 共享不可变资源 共享可变资源(可见性、操作原子性、禁止重排序) 1、不共享资源 ThreadLocal: 如何使用ThreadLocal 提高程序的效率 synchronized (Singleton.class) { if (null == singleton) { //解决多线程下的安全性问题

    9210

    面试官问线程安全List,看完再也不怕了!

    下面给大家总结一下吧,栈长在之前的文章《出场率比较高的一道多线程安全面试题》里面也讲过 ArrayList 的不安全性。 那么面试官会问你,既然 ArrayList 是线程安全的,怎么保证它的线程安全性呢?或者有什么替代方案? 往下看,看我如何碾压他! 大部分人会脱口而出:用Vector,这样只会让面试官鄙视! 你至少还得说得上这种: java.util.Collections.SynchronizedList 它能把所有 List 接口的实现类转换成线程安全List,比 Vector 有更好的扩展性和兼容性 ,SynchronizedList的构造方法如下: final List<E> list; SynchronizedList(List<E> list) { super(list); 总结 下次面试官问你线程安全List,你可以从 Vector > SynchronizedList > CopyOnWriteArrayList 这样的顺序依次说上来,这样才有带入感,也能体现你对知识点的掌握程度

    36620

    扫码关注腾讯云开发者

    领取腾讯云代金券