C#-多线程数据同步容易出现的异常问题
来源:互联网 发布:cms摄像头监控软件设置 编辑:程序博客网 时间:2024/05/16 06:12
问题描述:
当多个线程同时并发读写数据库的时候会抛出异常,这是比较典型的多线程并发同步所带来的问题,因为集合在读的过程中是不容许我们修改的,因此就需要引入锁的概念,加上读写锁就不会出现问题。
集合类通常不是线程安全的,多个阅读器可以安全的读取集合.但是对集合的任何修改都将为访问集合的所有线程生成不明确的结果.使用以下任何方法都可以令集合类是线程安全的
(1) 使用Synchronized 方法,则从该类派生包装,并通过该包装以独占方式访问集合
(2) 如果该类没有Synchronized 方法,则从该类派生并使用SyncRoot属性实现Synchronized 方法.
(3) 在访问该集合时对SyncRoot属性使用锁定机制
这一段时间在公司做多线程的东西比较多,所以把一些心得写了下来,对关注这一块的朋友有个提示作用.
大家可以看看以下代码:
class Program { static void Main(string[] args) { Program pg = new Program(); //写线程 Thread t1 = new System.Threading.Thread(new ThreadStart(pg.t1fun)); // 读线程 Thread t2 = new System.Threading.Thread(new ThreadStart(pg.t2fun)); //删线程 Thread t3 = new System.Threading.Thread(new ThreadStart(pg.t3fun)); t1.Start(); t2.Start(); t3.Start(); } ArrayList arraylist = new ArrayList(); public void t1fun() { while (true) { arraylist.Add("t1--写入"); System.Console.Out.WriteLine("写入"); System.Threading.Thread.Sleep(1000); } } public void t2fun() { while (true) { for (int i = arraylist.Count - 1; i >= 0; i--) { System.Console.Out.WriteLine("t2读取:"+(string)arraylist[i]); } System.Threading.Thread.Sleep(1000); } } public void t3fun() { while (true) { for (int i = arraylist.Count - 1; i >= 0; i--) { arraylist.RemoveAt(i); System.Console.Out.WriteLine("t3删除:t1"+i.ToString()); } System.Threading.Thread.Sleep(1000); } } }
这个测试程序得简单,大家一看就明白了你可以运行一下看看,程序一会就挂了,揭示异常:未处理的异常: System.ArgumentOutOfRangeException: 索引超出范围。必须为非负值并小于集合大小。
这就是因为多线程中对共享的集合资源同步引起的
下面是改后的代码:
class Program { static void Main(string[] args) { Program pg = new Program(); //写线程 Thread t1 = new System.Threading.Thread(new ThreadStart(pg.t1fun)); // 读线程 Thread t2 = new System.Threading.Thread(new ThreadStart(pg.t2fun)); //删线程 Thread t3 = new System.Threading.Thread(new ThreadStart(pg.t3fun)); t1.Start(); t2.Start(); t3.Start(); } ArrayList arraylist = new ArrayList(); public void t1fun() { while (true) { lock (arraylist.SyncRoot) { arraylist.Add("t1--写入"); } System.Console.Out.WriteLine("写入"); System.Threading.Thread.Sleep(1000); } } public void t2fun() { while (true) { lock (arraylist.SyncRoot) { for (int i = arraylist.Count - 1; i >= 0; i--) { System.Console.Out.WriteLine("t2读取:" + (string)arraylist[i]); } } System.Threading.Thread.Sleep(1000); } } public void t3fun() { while (true) { lock (arraylist.SyncRoot) { for (int i = arraylist.Count - 1; i >= 0; i--) { arraylist.RemoveAt(i); System.Console.Out.WriteLine("t3删除:t1" + i.ToString()); } } System.Threading.Thread.Sleep(1000); } } }
0 0
- C#-多线程数据同步容易出现的异常问题
- c-多线程同步的问题
- MySQL主从同步配置容易出现的问题以及解决方法
- xml容易出现的异常
- 关于C语言的memset容易出现的问题
- 使用remoteIO获取mic数据时容易出现的问题
- fragment的onResume方法中加载数据配置低的机型容易出现APP异常
- 多线程下数据同步问题
- 多线程的同步问题
- [c++]容易忽略的问题
- 04.多线程--04.【多线程卖票出现的数据安全问题】【同步代码块基本用法和原理】
- Java如何处理多线程的数据同步问题
- 通过接口解决多线程下的数据同步问题
- mysql 数据同步 出现Slave_IO_Running:No问题的解决方法小结
- 【mysql】 数据同步出现Slave_IO_Running:No问题的解决方法小结
- 系统和数据库容易出现的问题
- c++中new容易出现的问题
- 开发中容易出现的问题
- TCP-IP详解:AH(Authentication Header)
- cygwin 开发环境配置
- 【UML】— 对象图
- 设计模式学习(十七)————备忘录模式
- 《暗时间》笔记
- C#-多线程数据同步容易出现的异常问题
- 源码-JavaScript&jQuery交互式前端开发-第3章-函数、方法与对象-使用字面量语法创建对象
- 《java编程思想》第二章:一切都是对象
- JavaScript中This到底指哪个对象?
- C/C++中字符串数组及strlen()和sizeof()区别
- 模板类派生模板类
- 推导四对对应点单应矩阵的计算公式?
- 《Storm入门》总结
- IdeaVim插件使用技巧