分类:
2008-10-15 16:53:00
(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); } } } |