首页 > 编程语言 >C#之lock

C#之lock

时间:2024-02-05 17:34:35浏览次数:26  
标签:Console Thread C# lock System static using

原文链接:https://blog.csdn.net/u012563853/article/details/124767902

lock语法是:

private object o = new object();//创建一个对象
public void Work()
{
  lock(o)//锁住这个对象
  {
    //做一些必须按照顺序做的事情
  }
}

  目的是,在多线程中,使用lock后,能使该代码块按照指定的顺序执行,被lock这块代码已经被其中一个线程访问了,那么另外一个线程只能等待。

理论不明白的话,看下面分解。

1.看此代码,是从上面开始执行,先执行A,再执行B,这就是单线程程序,按照顺序执行的,此时结果是可以控制的。

2.我们增加了多线程,就是让A和B方法同时执行,此时,结果就是不可控制的。有时候先执行B方法,有时候先执行A方法。

先执行B方法。

先执行A方法 。

 对于为什么先执行A,后执行B,或者先执行B,后执行A,这个是操作系统根据CPU自动计算出来的。可见,我们的问题就来了。能不能这样,既能多线程执行,又可控制A和B的顺序呢?这个就要用到lock了。

3.所以,我们要的效果就是,在多线程的情况下,要么先执行A,要么先执行B。不能让A和B进行嵌套执行,必须按照顺序。程序一旦进入lock,那么就锁住,锁住的这段代码,此时只能有一个线程去访问,只有等这个线程访问结束了,其他线程才能访问。

为了增加对比,我们再增加一个C方法

 效果

 

 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp2
{
    class Program
    {
        static int a = 0;
        static int b = 0;
        private static object o = new object();
        static void Main(string[] args)
        {
            //A();
            //B();
            Thread t1 = new Thread(A);
            Thread t2 = new Thread(B);
            t1.Start();
            t2.Start();
            Thread t3 = new Thread(C);
            t3.Start();
            Console.ReadLine();
        }
        private static void A()
        {
            lock (o)
            {
                a = a + 2;
                Console.WriteLine("我是A方法,a=" + a);
                Thread.Sleep(5000);//暂停5秒
                b = b + 2;
                Console.WriteLine("我是A方法,b=" + b);
            }
        }
        private static void B()
        {
            lock (o)
            {
                b++;
                Console.WriteLine("我是B方法,b=" + b);
                Thread.Sleep(1000); //暂停1秒
                a++;
                Console.WriteLine("我是B方法,a=" + a);
            }
        }
        private static void C()
        {
            Console.WriteLine("我是C方法,随机出现");
        }
    }
}

  

拓展

其实lock相当于Monitor。

lock(o);
 
{
 
do 
 
}

等价于

  Monitor.Enter(o);
 
{
 
do
 
}
 
 Monitor.Exit(o);

  Enter相当于进入这个代码块,Exit是退出这个代码块。当这个代码块再运行的时候,其他线程就不能访问。Monitor中的{}可以去掉,不影响。

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp2
{
    class Program
    {
        static int a = 0;
        static int b = 0;
        private static object o = new object();
        static void Main(string[] args)
        {
            //A();
            //B();
            Thread t1 = new Thread(A);
            Thread t2 = new Thread(B);
            t1.Start();
            t2.Start();
            Thread t3 = new Thread(C);
            t3.Start();
            Console.ReadLine();
        }
        private static void A()
        {
            //lock (o)
            Monitor.Enter(o);
 
            a = a + 2;
            Console.WriteLine("我是A方法,a=" + a);
            Thread.Sleep(5000);//暂停5秒
            b = b + 2;
            Console.WriteLine("我是A方法,b=" + b);
 
            Monitor.Exit(o);
        }
        private static void B()
        {
            //lock (o)
            Monitor.Enter(o);
 
            b++;
            Console.WriteLine("我是B方法,b=" + b);
            Thread.Sleep(1000); //暂停1秒
            a++;
            Console.WriteLine("我是B方法,a=" + a);
 
            Monitor.Exit(o);
        }
        private static void C()
        {
            Console.WriteLine("我是C方法,随机出现");
        }
    }
}

  

 

标签:Console,Thread,C#,lock,System,static,using
From: https://www.cnblogs.com/Dongmy/p/18008527

相关文章

  • c++的类开发第一篇
    class_1什么是接口?类就是一种公共接口,公众(public)是使用类的程序,交互系统由类对象组成,而接口由编写类的人提供的方法组成。接口让程序员能够编写与类对象交互的代码,从而让程序能够使用类对象。例如,要计算string对象中包含多少个字符,您无需打开对象,而只需使用string类提供的s......
  • Proxmox 7.4 使用vgpu_unlock,为GTX1060开启vGPU支持
    本文在2021年发布的博客《Proxmox5.4使用vgpu_unlock,为GTX1060开启vGPU支持》,介绍了ProxmoxVE5.4上部署vGPUunlock的操作步骤。 后续有发布了在 ProxmoxVE7.x上支持vGPU的博客《Proxmox7.2部署DoraCloud桌面云,支持vGPU》,实现了通过3个脚本完成vGPU的配置。 ......
  • MCAL-MCU
    1.概述https://blog.csdn.net/qq_43629659/article/details/133050046 MCU模块提供了访问内核相关功能的API,如时钟配置、初始化RAM、设置低功耗模式、提供复位接口等等。1.1时钟上图左边位输入时钟源,右侧为输出时钟,需要选择合适的时钟源并通过倍频,分频来得到需要的时钟源。......
  • pytorch数据集MNIST训练与测试实例
      importosimporttorchimportnumpyasnpfromtorch.utils.dataimportDataLoaderfromtorchvision.datasetsimportMNISTfromtorchvision.transformsimportCompose,ToTensor,Normalizefromtorch.optimimportAdamimporttorch.nnasnnimporttorch.nn.......
  • MFC 自定义消息
    ▲Demo示例新建基于对话框的Demo程序。头文件://自定义数据类型,用来测试消息数据传递typedefstructtagStudent{CStringName;intAge;}Student_t;//Dlgheaderpublic:afx_msgvoidOnBnClickedButtonCustomMsg();afx_msgLRESULTOnCusto......
  • H3C 设备配置文件备份还原实验
    H3C设备配置文件备份还原实验H3C模拟器搭建实验,仅为参考(2024年1月14日)实验拓扑实验需求1、按照图示连接到真机,并配置IP地址(真机IP地址配置到VirtualBoxHost-OnlyEthernetAdapter网卡)2、R1保存当前配置3、在R1上开启FTP服务4、使用真机访问FTP服务,把R1的配置文件拷......
  • H3C vlan基础配置实验
    H3Cvlan基础配置实验实验拓扑实验需求1、按图示为PC配置IP地址2、SW1和SW2上分别创建vlan10和vlan20,要求PC1和PC3属于vlan10,PC2和PC4属于vlan203、SW1和SW2相连的接口配置为trunk类型,允许vlan10和vlan20通过4、测试效果,同一vlan的PC可以互通,不同vlan的PC无法互通实验步......
  • (13)TreeView1前面带CheckBox显示
     这些节点都是动态生成,再设置。原理还是在前面显示图片实现procedureTForm1.FormCreate(Sender:TObject);varpnode,node:TTreeNode;beginwithTreeView1.Itemsdobeginnode:=Add(nil,'Item1');//动态生成一个节点node.ImageIndex:=......
  • 项目中redis通用配置config
    packagecom.gm.wj.config;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.springframework.cache.annotation.CachingConfigurerS......
  • Docker基本原理与常用命令
    1docker架构K8S:CRI(ContainerRuntimeInterface)Client:客户端;操作docker服务器的客户端(命令行或者界面)Docker_Host:Docker主机;安装Docker服务的主机Docker_Daemon:后台进程;运行在Docker服务器的后台进程Containers:容器;从镜像创建的运行实例.可以被启动,开始,停止,删除.每......