http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 6815|回复: 1

[C#语言基础] c# lock (obj) 与 lock (this) 的用法区别

[复制链接]
发表于 2014-1-23 13:05:35 | 显示全部楼层 |阅读模式
c# lock (obj) 与 lock (this) 的用法区别

先来解释一下这两个的意思吧
lock(obj) 锁定 obj 这个对象
例如
[C#] 纯文本查看 复制代码
  Object m_Lock = new Object();
            lock (m_Lock)
            {
                
            }
这样的意思是说在这中间只能有一个线程来操作m_Lock 这个对象。
lock(this) 锁定 当前实例对象,如果有多个类实例的话,lock锁定的只是当前类实例,对其它类实例无影响。
可以看一下下面的代码
[C#] 纯文本查看 复制代码
delegate void SetTextCallback(string text);[/align][align=left]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());
}
[C#] 纯文本查看 复制代码
lock (m_Lock)
{

}
下面是一个执行加锁的类
[C#] 纯文本查看 复制代码
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;
            }
        }
    }
2011101523224458.jpg
大家看到每个线程执行的结果都是相同的。下面来看lock(this)
lock(this)
将oper类代码修改为如下:
[C#] 纯文本查看 复制代码
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;
            }
        }
    }
执行效果
2.jpg
大家看到每个线程执行的结果都是不同的。
分析:lock(this) 锁定的对象 是当前类实例,而每个线程操作的都是oper的新实例,lock(this)只对当前实例起作用,而 slgTotal 是类的静态变量,lock(this)实际上是没在起起我们想要的结果。下面再看一种lock(obj)的实例
3、lock(obj) 这个第一个obj的demo稍有不同,即把oper类的obj静态变量修改为变量,oper类修改为如下:
[C#] 纯文本查看 复制代码
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;
            }
        }
    }
执行效果
下载.png
此次运行结果和lock(this)结果是一样的。这是为什么呢?
总结:其实大家不要去看lock中锁定的是this,还是obj,大家只要关心多线程锁定的对象是不是为同一个对象。如果是同一个对象则会得到如上边的demo1结果,否则则如demo2和demo3中的结果,也是我们不想要的。
参考文章:



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2014-1-23 13:48:57 | 显示全部楼层
非常感谢你帮了我的大忙,真的太感谢你啦!
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-12-19 13:01

© 2014-2021

快速回复 返回顶部 返回列表