c#集合类的线程安全
即位于System.Collections命名空间下的集合,如Hashtable,ArrayList,Stack,Queue等.其均提供了线程同步的一个实现
集合线程同步的问题
public class Demo8
{
ArrayList list = new ArrayList(1000000);
public Demo8()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
} public void Task1(object obj)
{
for (int i = 0; i < 500000; i++)
{
list.Add(i);
} Console.WriteLine(DateTime.Now);
Console.WriteLine("Task1 count {0}", list.Count);
} public void Task2(object obj)
{
for (int i = 0; i < 500000; i++)
{
list.Add(i);
} Console.WriteLine("Task2 count {0}", list.Count);
}
}
![]()
与预期结果不同
调整为线程同步的集合
每种数据类型都包含一个静态的Synchronized方法,如
ArrayList list = ArrayList.Synchronized(new ArrayList(1000000));
调整后的结果
以下为注意点:
- IsSynchronized判断集合是否为线程同步
- 其内部通过给SyncRoot属性加锁进行同步(即Monitor.Enter)
自己控制锁
public class Demo8
{
ArrayList list = new ArrayList(1000000);
public Demo8()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
} public void Task1(object obj)
{
lock (list.SyncRoot)
{
for (int i = 0; i < 500000; i++)
{
list.Add(i);
}
} Console.WriteLine(DateTime.Now);
Console.WriteLine("Task1 count {0}", list.Count);
} public void Task2(object obj)
{
lock (list.SyncRoot)
{
for (int i = 0; i < 500000; i++)
{
list.Add(i);
}
}
Console.WriteLine("Task2 count {0}", list.Count);
}
}
![]()
这样的结果显然好看点.内部实现是在Add方法中做锁定.效果自然不是很好.
其他集合类也是类似的操作
泛型集合
可以看到原非泛型集合内部的线程同步集合,在每次操作均采用锁操作,但我们并非每个操作都需要锁,比如上面的2个线程操作.只需要2个锁就可以了,但使用内部集合的话则需要锁很多次,带来了性能问题.在.net 2.0泛型集合中,内部不再支持线程同步的集合,即使内部实现了线程同步的集合如List<T>的实现也为开发出来,即把lock的这个操作转嫁给开发者上面了.其实这样反而可以让我们更加了解线程同步的问题,如果真有需要的话,也可以自己实现一个了...
c#集合类的线程安全的更多相关文章
- 如何实现数组与List的相互转换?在 Queue 中 poll()和 remove()有什么区别?哪些集合类是线程安全的?
如何实现数组与List的相互转换? List转数组:toArray(arraylist.size()方法 数组转List:Arrays的asList(a)方法 /** * 〈一句话功能简述〉; * 〈 ...
- c# 变量,对象,静态类型,集合类的线程安全回顾
1.变量的线程安全性与变量的作用域有关. 2.对象 对象是类型的实例 在创建对象时,会单独有内存区域存储对象的属性和方法.所以,一个类型的多个实例,在执行时,只要没有静态变量的参与,应该都是线程安全的 ...
- Java哪些集合类是线程安全的?
早在jdk的1.1版本中,所有的集合都是线程安全的.但是在1.2以及之后的版本中就出现了一些线程不安全的集合,为什么版本升级会出现一些线程不安全的集合呢?因为线程不安全的集合普遍比线程安全的集合效率高 ...
- 自定义Dictionary支持线程安全
本文转载:http://www.cnblogs.com/kiddo/archive/2008/09/25/1299089.html 我们说一个数据结构是线程安全指的是同一时间只有一个线程可以改写它.这 ...
- Spring中获取request的几种方法,及其线程安全性分析
前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...
- .net framework 4 线程安全概述
线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的.早期的时候, ...
- 一招破解 Java 集合类面试题
今日招式:Java集合类面试题 Java集合类绝对是我们的老朋友了,Java技术江湖里,谁人不知,谁人不晓,它的使用率非常高,使用难度却也不大,这也导致了很多人对它不屑一顾,殊不知其中却暗藏玄机,今天 ...
- 【转】SpringMVC,获取request的几种方法,及线程安全性
作者丨编程迷思 https://www.cnblogs.com/kismetv/p/8757260.html 概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对 ...
- [No000016E]Spring 中获取 request 的几种方法,及其线程安全性分析
前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...
随机推荐
- https证书申请
因为要为海外组的aws设置https证书,由于使用的是新的域名,所以要先申请购买证书,然后设置上去.由于是第一次做这件事.所以过程有些坎坷. 先购买https证书.看了几家,感觉GoDad ...
- TweenMax动画库学习(三)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) ...
- javascript 弹出的窗口返回值给 父窗口
直接上代码,有些地方可以用到: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <H ...
- Mac OS X下GnuPlot的安装和配置(无法set term png等图片输出)
今天使用gitstats分析git repo的活动信息,发现其内部使用gnuplot,结果发现无法生成png图片,进入gnuplot的shell发现无法设置png格式输出.如下 gnuplot> ...
- 教了几天C语言 C语言竞赛------家长们你们为什么这么急!!
由于工大某些传统,暑假放一个月,想想有很多事情要做,而且回去也是热着,倒不如不回家了,在哈尔滨正好避暑,又能轻轻松松的吧事情做了,暑假还能有个好的休息,这样想着,最终决定不回去了.其实不回去的话,就会 ...
- js:合同-已知起始日期、年限,自动计算截止日期
dateAddYear('2016-01-01', '3') ;//返回:2018-12-31 浏览器:ie11,ff 46.0.1(成功)360v8.1(急速模式,成功) 浏览器:360v8.1(兼 ...
- 大数据时代的技术hive:hive的数据类型和数据模型
在上篇文章里,我列举了一个简单的hive操作实例,创建了一张表test,并且向这张表加载了数据,这些操作和关系数据库操作类似,我们常把hive和关系数据库进行比较,也正是因为hive很多知识点和关系数 ...
- hdu 5510 Bazinga KMP+尺取法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 题意:至多50组数据,每组数据至多500个字符串,每个字符串的长度最长为2000.问最大的下标( ...
- 一步步学习NHibernate(8)——HQL查询(2)
请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,老魏带着大家学习了HQL语句,发现HQL语句还是非常不错的,尤其是在懒加载的时候,书写起来比较的舒服,但是这里老魏 ...
- UIScrollView解决touchesBegan等方法不能触发的解方案
新建一个类继承自UIScrollView 并重写下面的方法 -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [su ...