C#-多线程数据同步容易出现的异常问题
2016-09-27 08:18
323 查看
问题描述:
当多个线程同时并发读写数据库的时候会抛出异常,这是比较典型的多线程并发同步所带来的问题,因为集合在读的过程中是不容许我们修改的,因此就需要引入锁的概念,加上读写锁就不会出现问题。集合类通常不是线程安全的,多个阅读器可以安全的读取集合.但是对集合的任何修改都将为访问集合的所有线程生成不明确的结果.使用以下任何方法都可以令集合类是线程安全的
(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); } } }
相关文章推荐
- Delphi中多线程用Synchronize实现VCL数据同步显示 解决在线程中操作控件出现问题
- mybatis多线程插入数据时出现的问题
- 04.多线程--04.【多线程卖票出现的数据安全问题】【同步代码块基本用法和原理】
- fragment的onResume方法中加载数据配置低的机型容易出现APP异常
- java线程研究---(7)Thread同步:多线程数据共用会产生问题
- 解决mysql插入数据时出现Incorrect string value: '\xF0\x9F...' for column 'name' at row 1的异常 这个问题,原因是UTF-8编码有可
- TCP同步传送数据示例以及可能出现问题分析
- synchronized解决多线程共享数据同步问题
- 关于Android中多线程中异常捕获出现的问题和解决办法
- mysql 数据同步 出现Slave_IO_Running:No问题的解决方法小结
- 如何避免mysql 主从同步中由于数据记录找不到和主键重复错误导致的同步异常问题
- mysql 数据同步 出现Slave_IO_Running:No问题的解决方法小结
- 关于在form中通过ajax请求传递数据时出现异常的问题
- TCP同步传送数据示例以及可能出现问题分析
- 使用synchronized关键字解决共享数据同步问题:多线程门票销售
- Servlet的多线程单实例导致的数据同步问题
- Java如何利用synchronized处理多线程的数据同步问题
- 为什么多线程线程处理数据经常出现singnal异常,寻址异常
- 【mysql】 数据同步出现Slave_IO_Running:No问题的解决方法小结