本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象。由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧。

其实多线程的同步,使用同步锁的方法用了好多次,今天无意中看到MSDN中,建议用:

 private static readonly object locker1 = new object();
private readonly object locker2 = new object();

备注:原文并没有加readonly,是我后来自己加进去的。

我不仅思考了一下他们的区别。

然后我写了一段代码进行测试,测试类代码如下:

    /// <summary>
/// 跨线程操作UI的时候传递的参数,本文为了显示消息,所以简单的封装了一个
/// </summary>
public class MyEventArgs : EventArgs
{
public readonly string Message = string.Empty;
public MyEventArgs(string msg)
{
this.Message = msg;
}
}
/// <summary>
/// 测试类,用于测试2种锁的区别
/// </summary>
public class LockTest
{
//2个锁
private static readonly object Locker1 = new object();
private readonly object Locker2 = new object(); /// <summary>
/// 跨线程操作UI的委托和事件
/// </summary>
public delegate void MessageEventHandler(object sender, MyEventArgs e);
public event MessageEventHandler MessageEvent;
public void OnMessage(MyEventArgs e)
{
if (this.MessageEvent != null) MessageEvent(this, e);
} //要锁的变量,通过它可以看出2种锁在不同情况下的效果
private int num = ;
//实例名字
private readonly string Name;
public LockTest(string name)
{
Name = name;
}
//第一种锁执行的方法
public void AddNum1()
{
lock (Locker1)
{
num = ;
ShowMessage();
}
}
//第二种锁执行的方法
public void AddNum2()
{
lock (Locker2)
{
num = ;
ShowMessage();
}
}
//锁内的一些操作,并通过事件,把关键的消息显示到主线程中的UI里
private void ShowMessage()
{
string msg = "";
for (int i = ; i < ; i++)
{
num += ;
msg = string.Format("线程 [{0}],实例[{1}]中num的值是[{2}]", Thread.CurrentThread.Name, this.Name, num);
OnMessage(new MyEventArgs(msg));
Thread.Sleep();
}
msg = string.Format("======线程 [{0}]执行完毕======", Thread.CurrentThread.Name);
OnMessage(new MyEventArgs(msg));
}
}

测试用的类写完了,开始测试:

首先测试单个实例、多线程,2种锁的区别:

        private void button1_Click(object sender, EventArgs e)
{
LockTest test = new LockTest("LockTest 1");
test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);
listBox1.Items.Clear();
for (int i = 0; i <= 2; i++)
{
Thread a = new Thread(new ThreadStart(test.AddNum1));
a.Name = i.ToString();
a.Start();
}
} private void button2_Click(object sender, EventArgs e)
{
LockTest test = new LockTest("LockTest 1");
test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);
listBox1.Items.Clear();
for (int i = 0; i <= 2; i++)
{
Thread a = new Thread(new ThreadStart(test.AddNum2));
a.Name = i.ToString();
a.Start();
}
}

  输出结果一模一样:

得出结论:如果对一个实例,多线程访问的时候,2种锁是没有区别的。

下面是测试多个实例的情况(静态锁):

        private void button3_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
for (int i = ; i <= ; i++)
{
LockTest test = new LockTest("LockTest " + i.ToString());
test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);
Thread a = new Thread(new ThreadStart(test.AddNum1));
a.Name = i.ToString();
a.Start();
}
}

得到结果:

得出结论,在静态锁面前,线程依旧要排队,虽然不是一个实例,但是锁是唯一的,线程只认锁,所以线程并没有并发!

继续测试(非静态的锁):

        private void button4_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
for (int i = ; i <= ; i++)
{
LockTest test = new LockTest("LockTest " + i.ToString());
test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);
Thread a = new Thread(new ThreadStart(test.AddNum2));
a.Name = i.ToString();
a.Start();
}
}

得到的结果:

得出结论:非静态锁的时候,多线程并发了,一起在工作。

其实,测试的结果之前也能猜想出来,只不过,不测试下,心里总是觉得没底,呵呵,测试完了,也就彻底释然了!

窗体中,用于事件回调,显示到UI里的代码在这里:

delegate void MessageHandler(string msg);
public void MessageCallBack(object sender, MyEventArgs e)
{
MessageHandler handler = new MessageHandler(ShowMessage);
this.Invoke(handler, new object[] { e.Message });
} public void ShowMessage(string msg)
{
this.listBox1.Items.Add(msg);
}

c#中多线程同步Lock(锁)的研究以及跨线程UI的操作的更多相关文章

  1. c#中多线程同步Lock(锁)的研究以及跨线程UI的操作 (转)

    https://www.cnblogs.com/tommyheng/p/4104552.html 本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做de ...

  2. c#中Lock(锁)的研究以及跨线程UI的操作

    本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧.       其实多线程 ...

  3. Delphi 中多线程同步的一些处理方法

    Delphi 中多线程同步的一些处理方法   当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...

  4. python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...

  5. [delphi]在DLL中多线程同步Synchronize卡死问题

    在dll中多线程同步调用Synchronize不可以,会出现假死卡住的现象.可通过Sendmessage实现. 转网上其他文章解释: Application.Initialize; begin     ...

  6. Java中多线程的使用(超级超级详细)线程池 7

    Java中多线程的使用(超级超级详细)线程池 7 什么是线程池? 线程池是一个容纳多个线程的容器,线程池中的线程可以重复使用,无需反复创建线程而消耗过多的资源 *使用多线程的好处: 1.降低消耗,减少 ...

  7. Java中多线程的使用(超级超级详细)线程安全原理解析 4

    Java中多线程的使用(超级超级详细)线程安全 4 什么是线程安全? 有多个线程在同时运行,这些线程可能会运行相同的代码,程序运行的每次结果和单线程运行的结果是一样的,而且其他变量的值也和预期的值一样 ...

  8. C#关于多线程及线程同步 lock锁的应用

    Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...

  9. Java多线程---同步与锁

    一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...

随机推荐

  1. Zip 压缩和解压技术在 HTML5 中的应用

    JSZip 是一款可以创建.读取.修改 .zip 文件的 javaScript 工具.在 web 应用中,免不了需要从 web 服务器中获取资源,如果可以将所有的资源都合并到一个 .zip 文件中,这 ...

  2. sql server left 和right 函数

    参考文章:微信公众号文章 一直对sql中的left和right有误解,一直以为它是这样的. 执行这样一句: ) leftNum ) rightNum 出现的结果是这样的: 而我心中这样认为: 我认为只 ...

  3. WPF's Style BasedOn

    <Style x:Key="BasedStyle" BasedOn="{x:Null}" TargetType="{x:Type Control ...

  4. ABP总体介绍

    ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点, ...

  5. python之最强王者(4)——字符串

    1.Python 中文编码 前面章节中我们已经学会了如何用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界" ...

  6. 你必须知道的Microsoft SQL Server一

    不知道为什么我Win10环境下安装的Sqlserver2012,智能提示的功能基本上没有用,没办法,我还是选择安装插件SQL Prompt 5吧.下载地址:http://www.uzzf.com/so ...

  7. CString转换为LPSTR和LPSTR转化为CString

    一.CString转换为LPSTR 方法一: CString strFileName LPSTR lpstr - strFileName.GetBuffer(); strFileName.Releas ...

  8. jasmine test 页面测试工具

    before((request, response) -> { response.header("Access-Control-Allow-Origin", "ht ...

  9. handlebars.js的运用与整理

    最近在做部门的技术分享网站,主要是一些文章的列表和演讲信息展示,内容比较规律,复用性较高.同事推荐了 handlebars.js.用来看看. handlebars.js是一种静态JS模板,用起来还蛮简 ...

  10. Drop all the tables, stored procedures, triggers, constraints and all the dependencies in one SQL statement

    Is there any way in which I can clean a database in SQl Server 2005 by dropping all the tables and d ...