C# .net 多线程中集合数据同步(转)
集合类通常不是线程安全的,多个阅读器可以安全的读取集合.但是对集合的任何修改都将为访问集合的所有线程生成不明确的结果.使用以下任何方法都可以令集合类是线程安全的
(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); } } }
原地址Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1804617