一、Lock定义

    lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。

     在多线程中,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。

    而在.NET中最好了解一下进程、应用域和线程的概念,因为Lock是针对线程一级的,而在.NET中应用域是否会对Lock起隔离作用,我的猜想是,即不在同一应用域中的线程无法通过Lock来中断;另外也最好能了解一下数据段、代码段、堆、栈等概念。

    在C# lock关键字定义如下:

    lock(expression) statement_block,其中expression代表你希望跟踪的对象,通常是对象引用。

    如果你想保护一个类的实例,一般地,你可以使用this;如果你想保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。

而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。

二、简单例子

 

  1.  
    using System;
  2.  
    using System.Collections;
  3.  
    using System.Collections.Generic;
  4.  
    using System.Threading;
  5.  
    namespace ConsoleApplication1
  6.  
    {
  7.  
    class Program
  8.  
    {
  9.  
    static void Main(string[] args)
  10.  
    {
  11.  
    Thread thread1 = new Thread(new ThreadStart(ThreadStart1));
  12.  
    thread1.Name = "Thread1";
  13.  
    Thread thread2 = new Thread(new ThreadStart(ThreadStart2));
  14.  
    thread2.Name = "Thread2";
  15.  
    Thread thread3 = new Thread(new ThreadStart(ThreadStart3));
  16.  
    thread3.Name = "Thread3";
  17.  
    thread1.Start();
  18.  
    thread2.Start();
  19.  
    thread3.Start();
  20.  
    Console.ReadKey();
  21.  
    }
  22.  
    static object _object = new object();
  23.  
    static void Done(int millisecondsTimeout)
  24.  
    {
  25.  
    Console.WriteLine(string.Format("{0} -> {1}.Start", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));
  26.  
    //下边代码段同一时间只能由一个线程在执行
  27.  
    lock (_object)
  28.  
    {
  29.  
    Console.WriteLine(string.Format("{0} -> {1}进入锁定区域.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));
  30.  
    Thread.Sleep(millisecondsTimeout);
  31.  
    Console.WriteLine(string.Format("{0} -> {1}退出锁定区域.", DateTime.Now.ToString("HH:mm:ss"), Thread.CurrentThread.Name));
  32.  
    }
  33.  
    }
  34.  
    static void ThreadStart1()
  35.  
    {
  36.  
    Done(5000);
  37.  
    }
  38.  
    static void ThreadStart2()
  39.  
    {
  40.  
    Done(3000);
  41.  
    }
  42.  
    static void ThreadStart2()
  43.  
    {
  44.  
    Done(1000);
  45.  
    }
  46.  
    }
  47.  
    }

 

三、简单解释一下执行过程

先来看看执行过程,代码示例如下:

        private static object  ojb = new object();

        lock(obj)

        {

                 //锁定运行的代码段

        }
  假设线程A先执行,线程B稍微慢一点。线程A执行到lock语句,判断obj是否已申请了互斥锁,判断依据是逐个与已存在的锁进行object.ReferenceEquals比较(此处未加证实),如果不存在,则申请一个新的互斥锁,这时线程A进入lock里面了。

这时假设线程B启动了,而线程A还未执行完lock里面的代码。线程B执行到lock语句,检查到obj已经申请了互斥锁,于是等待;直到线程A执行完毕,释放互斥锁,线程B才能申请新的互斥锁并执行lock里面的代码。

posted @ 2022-08-15 09:01 zhlhl 阅读(133) 评论(0) 推荐(0) 编辑
摘要: 在wpf中可以使用许多方法执行异步操作。利用.NET的芳芳就是手动创建一个新的System.Threading.Thread对象,提供一步代码,并使用THread.Start()方法加载代码。这种方法很有用,因为Thread对象没有隐瞒任何内容。如果你愿意,可以创建几十个线程,设置他们的优先级,控制 阅读全文
posted @ 2022-06-20 15:29 zhlhl 阅读(500) 评论(0) 推荐(0) 编辑
摘要: Invoke和BeginInvoke 区别 Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托。 Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上异步执行指定委托。 (一)Control的I 阅读全文
posted @ 2022-02-22 12:51 zhlhl 阅读(73) 评论(0) 推荐(0) 编辑
摘要: static 静态可修饰类、类的构造函数,类的成员等; [访问修饰符] static class 类名 { //类的成员} static 静态函数构造名() { //语句} [访问修饰符] static 数据类型 数据成员 应用场景:类、类的构造函数或类的成员所引用或操作的信息与类有关,而与类的实例 阅读全文
posted @ 2021-12-23 11:08 zhlhl 阅读(199) 评论(0) 推荐(0) 编辑
摘要: C#6.0 阅读全文
posted @ 2021-12-15 18:31 zhlhl 阅读(421) 评论(0) 推荐(0) 编辑
摘要: 异步调用是CLR为开发者提供的一种重要的编程手段,它也是构建高性能、可伸缩应用程序的关键。在多核CPU越来越普及的今天,异步编程允许使用非常少的线程执行很多操作。我们通常使用异步完成许多计算型、IO型的复杂、耗时操作,去取得我们的应用程序运行所需要的一部分数据。在取得这些数据后,我们需要将它们绑定在 阅读全文
posted @ 2021-09-18 13:33 zhlhl 阅读(423) 评论(0) 推荐(0) 编辑
摘要: 调用快捷键 Ctrl+Alt+C 诊断工具快捷键 Ctrl+Alt+F2 位置: 调试 >> 窗口 >> 调用堆栈说明:任何一个项目都会对项目进行各种层次和模块的划分,不管新手老手,在调试代码的时候(尤其是维护项目,修改别人的代码)还是经常会因为不知道代码是如何传递执行的而产生苦恼。如下面跟踪到代码 阅读全文
posted @ 2021-09-17 18:51 zhlhl 阅读(1345) 评论(0) 推荐(1) 编辑
摘要: 目录 自动属性 隐式类型 对象初始化器与集合初始化器 匿名类 扩展方法 Lambda表达式 EDM概述 EDM之CSDL EDM之SSDL EDM之MSL EDM中存储过程的设计 EDM中ComplexType的设计 实体数据模型映射方案 各种使用方式总结 使用技巧及需要注意的问题 几种方法的性能分 阅读全文
posted @ 2021-08-25 10:30 zhlhl 阅读(396) 评论(0) 推荐(0) 编辑
摘要: WPF滑块控件(Slider)的自定义样式 前言 每次开发滑块控件的样式都要花很久去读样式代码,感觉有点记不牢,所以特此备忘。 自定义滑块样式 首先创建项目,添加Slider控件。 然后获取Slider的Window样式,如下图操作。 然后弹出界面如下.我们点击确定。 点击确定后,我们的页面的Res 阅读全文
posted @ 2021-07-28 14:50 zhlhl 阅读(314) 评论(0) 推荐(0) 编辑
摘要: 这段是MSDN上对依赖属性(DependencyProperty)的描述。主要介绍了两个方面,WPF中提供了可用于扩展CLR属性的服务;被这个服务支持的属性称为依赖属性。单看描述,云里雾里的,了解一个知识,首先要知道它产生的背景和为什么要有它,那么WPF引入依赖属性是为了解决什么问题呢?从属性说起属 阅读全文
posted @ 2021-05-24 10:55 zhlhl 阅读(74) 评论(0) 推荐(0) 编辑
摘要: WPF图形之:Path详解 飞鹰再现 2013-10-26 16:03:56 7522 收藏 6 分类专栏: WinForm&amp;WPF 文章标签: WPF 图形 先看显示效果: XAML(代码A):<Page xmlns="http://schemas.microsoft.com/winfx/ 阅读全文
posted @ 2021-05-21 13:52 zhlhl 阅读(123) 评论(0) 推荐(0) 编辑
摘要: 布局系统 提及 MeasureOverride、ArrangeOverride,大家都会认为这是 WPF 布局系统给我们提供的两个可供重写的方法。然而,这两个方法其实也是 FrameworkElement 才提供的。 真正布局的方法是 Measure 和 Arrange,而可供重写的方法是 Meas 阅读全文
posted @ 2021-05-21 13:26 zhlhl 阅读(437) 评论(0) 推荐(1) 编辑
摘要: file:///C:/WPF%20&%20MVVM/%E6%95%99%E7%A8%8B/%E5%88%A9%E5%88%83%20MVVMLight/%E5%88%A9%E5%88%83%20MVVMLight%201%EF%BC%9AMVVMLight%E4%BB%8B%E7%BB%8D%E4% 阅读全文
posted @ 2021-04-06 13:53 zhlhl 阅读(105) 评论(0) 推荐(0) 编辑
摘要: FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "username", DateTime.Now, DateTime.Now.AddDays(365), true, string.Format("{0}:{1}" 阅读全文
posted @ 2019-12-13 14:45 zhlhl 阅读(289) 评论(0) 推荐(0) 编辑
摘要: 1.利用 “+”(加号)运算符: string str = “Hello”+ “World”; console.WriteLine(str);//输出 “HelloWorld” 2.使用 Join()方法: Join()方法是String类的静态方法,就是说String是类的方法,不是实例的方法,直 阅读全文
posted @ 2019-11-19 09:30 zhlhl 阅读(5238) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示