博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程中lock的使用
阅读量:7024 次
发布时间:2019-06-28

本文共 2877 字,大约阅读时间需要 9 分钟。

lock的定义

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

lock关键字定义

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

简单介绍一下lock的执行过程

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

        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里面的代码。

 

以上是网上的说话,下面谈谈我的理解

一般来说多线程中,使用有静态变量这种,或者你想保证数据完全执行到的就需要加锁了

需要注意的是:

一:多线程加锁范围太大,虽然会避免逻辑上的问题,难免会降低程序的效率。

二:该锁的不锁会导致莫名奇妙的错误

三:加锁方式不合适,也会降低程序的效率

实例

下面的例子,仅供参考,只是自己随手一写,也没有测试代码的正确度,主要是对线程锁lock的了解

有这样一个例子,我在新增一个方法的时候,同时想在表格新增其他字展示在表格里面

首先是查询所有人的信息

///         /// 获取学生的集合        ///         /// 
public static List
GetStudent() { List
list = new List
(); list.Add(new Student() { Sid = 1, Sname = "张三", Sex = "男", Age = 12 }); list.Add(new Student() { Sid = 2, Sname = "李四", Sex = "女", Age = 13 }); list.Add(new Student() { Sid = 3, Sname = "王五", Sex = "男", Age = 14 }); list.Add(new Student() { Sid = 4, Sname = "赵六", Sex = "男", Age = 15 }); return list; }

获取一下person的消息

_spDic为了记录除了表格本身之外的数据,这里当然会出错,我只是做一个赋值,用_spDic记录数据而已

static Dictionary
_spDic = new Dictionary
(); // public static List
GetPeopleItem() { List
list1 = GetStudent(); List
list2 = new List
(); Person person = new Person(); foreach (Student item in list1) { person.Pid = item.Sid; person.Pname = item.Sname; person.Sex = item.Sex; person.Age = item.Age; list2.Add(person); if (person.Pid > 0) { lock (_spDic) { _spDic.Add(person, item); } } } return list2; }

调用static void Main(string[] args)

{            List
list = GetPeopleItem(); foreach (var item in list) { Console.WriteLine(item.Pid); Task.Factory.StartNew(() => { //这里面实现了功能的新增             .............. lock (_spDic) { _spDic.Remove(item); } }); } Console.ReadKey(); }

这时候我在实现新增后,就移除了他的数据也是需要加锁的,这样才能保证数据完全可以执行到.

 注意

应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:     1)如果实例可以被公共访问,将出现 lock (this) 问题;     2)如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题;     3)由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock("myLock") 问题;     最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。

 

转载于:https://www.cnblogs.com/liu23/p/9136749.html

你可能感兴趣的文章
could not bind socket. address and port are already in use
查看>>
asa防火墙基本上网综合实验
查看>>
seq的一些用法示例
查看>>
Java中xml与json的相互转换
查看>>
GNS3综合实验_0130
查看>>
Python模块filecmp 文件比较
查看>>
查看mysql读和写的量
查看>>
Python 使用 Xlrd/xlwt 操作 Excel
查看>>
python将日志导入数据库代码案例
查看>>
MySQL二进制包安装实例 ( 5.5 、5.6 共存 )
查看>>
zabbix 之 安装配置手册(全)
查看>>
算法学习之路|万绿丛中一点红
查看>>
Zabbix低级发现结合jstat命令自动监控Java进程(jdk 1.8版本)
查看>>
zabbix3.4.4集成graphtrees图文笔记
查看>>
国家网络安全产业园区落户北京
查看>>
算法学习之路|wifi密码
查看>>
V-4-3 访问vCenter与操作
查看>>
运维DBA的4大纪律9项注意【转】
查看>>
写python的常用工具及设置
查看>>
PLSQL Developer软件使用大全
查看>>