.NET多线程小记(6):线程同步
2009-11-06 15:15 敏捷的水 阅读(564) 评论(0) 编辑 收藏 举报同步块的机制:
- 在.NET被加载时初始化同步块数组
- 每一个被分配在堆上的对象都会包含两个额外的字段,其中一个存储类型指针,而另外一个就是同步块索引,初始时被赋值为-1.
- 当一个线程试图使用该对象进入同步时,会检查该对象的同步索引。如果索引为负数,则会在同步块数组中寻找或者新建一个同步块,并且把同步块的索引值写入该对象的同步索引中。如果该对象的同步索引不为负值,则找到该对象的同步块并且检查是否有其他线程在使用该同步块,如果有则进入等待状态,如果没有则声明使用该同步块。
- 当一个对象退出同步时,该对象的同步索引被赋值为-1,并且对应的同步块数组内的同步块被视为不再使用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace MultiThreadTest { class Program { static void Main(string[] args) { Console.WriteLine("测试静态方法同步?"); for (int i = 0; i < 5; i++) { Thread t = new Thread(Lock.Add1); t.Start(); } Thread.Sleep(10 * 1000); Console.WriteLine("测试成成员方法同步"); Lock l = new Lock(); for (int i = 0; i < 5; i++) { Thread t = new Thread(l.Add2); t.Start(); } Console.Read(); } } public class Lock { // 用来同步静态方法 private static object o1 = new object(); private static int i1 = 0; // 用来同步成员方法 private object o2 = new object(); private int i2 = 0; public static void Add1(object state) { lock (o1) { Console.WriteLine("before add:i1 = {0}", i1); Thread.Sleep(1000); i1++; Console.WriteLine("after add :i1 = {0}", i1); } } public void Add2(object state) { lock (o2) { Console.WriteLine("before add:i1 = {0}", i2); Thread.Sleep(1000); i2++; Console.WriteLine("after add :i1 = {0}", i2); } } } }
注意:对静态方法的同步,一般采用静态私有的引用成员,而对成员方法的同步,一般采用私有的引用成员。值类型的对象非配在堆栈上,没有同步索引字段,所以不能用来进行同步。
扫码关注公众号,了解更多管理,见识,育儿等内容
作者: 王德水
出处:http://www.cnblogs.com/cnblogsfans
版权:本文版权归作者所有,转载需经作者同意。
出处:http://www.cnblogs.com/cnblogsfans
版权:本文版权归作者所有,转载需经作者同意。