c# lock (obj) 与 lock (this) 区别

http://www.cnblogs.com/yuqilin/archive/2011/10/15/2213766.html

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中的结果,也是我们不想要的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值