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


    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());
    
            }
    
    1lock(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)
    
     
    
    2lock(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)的实例
    
    3lock(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中的结果,也是我们不想要的。

    摘自:李国清

  • 相关阅读:
    git的merge功能
    linux实用命令
    记录maven的一些命令
    java模拟报文
    spring boot利用swagger和spring doc生成在线和离线文档
    java将类和函数封装成jar
    spring cloud微服务搭建(一)
    linux根目录扩容
    快速上手UIView动画
    PHP变量
  • 原文地址:https://www.cnblogs.com/rinack/p/3101577.html
Copyright © 2020-2023  润新知