lock(obj) 锁定obj 对象 lock(this) 锁定 当前实例对象,如果有多个类实例的话,lock锁定的只是当前类实例,对其它类实例无影响。 直接上代码。 主窗体代码如下: delegate void SetTextCallback(string text); public Form1() { InitializeComponent(); } /// <summary> /// 利用委托设置 文本框内容 /// </summary> /// <param name="text"></param> public void SetText(string text) { if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = this.textBox1.Text + "\r\n" + text; } } private void button1_Click(object sender, EventArgs e) { textBox1.Text = ""; Thread[] thd = new Thread[500]; int intI = 0; for (intI = 0; intI < 50; intI++) { thd[intI] = new Thread(new ParameterizedThreadStart(thdText)); thd[intI].Name = " Thread" + intI.ToString(); thd[intI].IsBackground = true; thd[intI].Start(intI); } } /// <summary> /// 线程调用的方法 /// </summary> /// <param name="obj"></param> private void thdText(object obj) { oper op = new oper(); int intI = Convert.ToInt32(obj); SetText(op.addition()); } 1、lock(obj) 添加oper类,代码如下: public class oper { private static object obj = new object(); private static Single slgTotal; public string addition() { lock (obj) { int intI = 0; slgTotal = 0; for (intI = 0; intI <= 50; intI++) { slgTotal = slgTotal + intI; Thread.Sleep(5); } return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name; } } } 执行结果如下:
大家看到每个线程执行的结果都是相同的。下面来看lock(this) 2、lock(this) 将oper类代码修改为如下: public class oper { private static object obj = new object(); private static Single slgTotal; public string addition() { lock (this) { int intI = 0; slgTotal = 0; for (intI = 0; intI <= 50; intI++) { slgTotal = slgTotal + intI; Thread.Sleep(5); } return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name; } } } 执行结果如下:
大家看到每个线程执行的结果都是不同的。 分析:lock(this) 锁定的对象 是当前类实例,而每个线程操作的都是oper的新实例,lock(this)只对当前实例起作用,而slgTotal 是类的静态变量,lock(this)实际上是没在起起我们想要的结果。下面再看一种lock(obj)的实例 3、lock(obj) 这个第一个obj的demo稍有不同,即把oper类的obj静态变量修改为变量,oper类修改为如下: public class oper { private object obj = new object(); private static Single slgTotal; public string addition() { lock (obj) { int intI = 0; slgTotal = 0; for (intI = 0; intI <= 50; intI++) { slgTotal = slgTotal + intI; Thread.Sleep(5); } return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name; } } } 执行结果如下:
此次运行结果和lock(this)结果是一样的。这是为什么呢?
总结:其实大家不要去看lock中锁定的是this,还是obj,大家只要关心多线程锁定的对象是不是为同一个对象。如果是同一个对象则会得到如上边的demo1结果,否则则如demo2和demo3中的结果,也是我们不想要的。
摘自:李国清