ASP.NET中lock 的用法
ASP.NET中lock 的用法
ASP.NET中lock 的用法每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
一、ASP.NET中lock关键字定义
lock(expression) statement_block
expression代表你希望跟踪的对象,通常是对象引用。
statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。
二、为什么要lock,lock了什么?
当我们使用线程的时候,效率最高的方式当然是异步,即各个线程同时运行,其间不相互依赖和等待。但当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源在同一时刻只能被一个线程操作,以确保每个操作都是有效即时的,也即保证其操作的原子性。lock是C#中最常用的同步方式,格式为lock(objectA){codeB} 。
lock(objectA){codeB} 看似简单,实际上有三个意思,这对于适当地使用它至关重要:
1. objectA被lock了吗?没有则由我来lock,否则一直等待,直至objectA被释放。
2. lock以后在执行codeB的期间其他线程不能调用codeB,也不能使用objectA。
3. 执行完codeB之后释放objectA,并且codeB可以被其他线程访问。
三、lock实例
using System;
using System.Threading;
namespace ThreadSimple
{
internal class Account
{
int balance; //余额
Random r=new Random();
internal Account(int initial)
{
balance=initial;
}
internal int Withdraw(int amount) //取回、取款
{
if(balance<0)
{
//如果balance小于0则抛出异常
throw new Exception("NegativeBalance");//负的 余额
}
//下面的代码保证在当前线程修改balance的值完成之前
//不会有其他线程也执行这段代码来修改balance的值
//因此,balance的值是不可能小于0的
lock(this)
{
Console.WriteLine("CurrentThread:"+Thread.CurrentThread.Name);
//如果没有lock关键字的保护,那么可能在执行完if的条件判断(成立)之后
//另外一个线程却执行了balance=balance-amount修改了balance的值
//而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了
//但是,这个线程却继续执行 balance=balance-amount,所以导致balance可能小于0
if(balance>=amount)
{
Thread.Sleep(5);
balance=balance-amount;
return amount;
} else
{
return 0;
//transactionrejected
}
}
}
internal void DoTransactions()//取款事务
{
for (int i = 0; i < 100; i++)
{
Withdraw(r.Next(-50, 100));
}
}
}
internal class Test
{
static internal Thread[] threads=new Thread[10];
public static void Main()
{
Account acc=new Account(0);
for(int i=0;i<10;i++)
{
Thread t=new Thread(new ThreadStart(acc.DoTransactions));
threads[i]=t;
}
for (int i = 0; i < 10; i++)
{
threads[i].Name = i.ToString();
}
for (int i = 0; i < 10; i++)
{
threads[i].Start();
Console.ReadLine();
}
}
}
}
四、Lock的对象选择问题
1、为什么不能lock值类型
比如lock(1)呢?lock的参数必须是基于引用类型的对象,不要是基本类型像bool,int什么的,这样根本不能同步,原因是lock的参数要求是对象,如果传入int,势必要发生装箱操作,这样每次lock的都将是一个新的不同的对象。
2、Lock字符串
那么lock("xxx")字符串呢?MSDN上的原话是:
锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。 这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。
3、MSDN推荐的Lock对象
通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。
而且lock(this)只对当前对象有效,如果多个对象之间就达不到同步的效果。
而自定义类推荐用私有的只读静态对象,比如:
private static readonly object obj = new object();
为什么要设置成只读的呢?这时因为如果在lock代码段中改变obj的值,其它线程就畅通无阻了,因为互斥锁的对象变了,object.ReferenceEquals必然返回false。
4、lock(typeof(Class))
与锁定字符串一样,范围太广了。
5、推荐使用以下方法lock
private static object asyncLock=new object();
lock(asyncLock)
- ASP.NET中lock 的用法
- with(nolock)的用法
- python程序锁教程(在python里协程使用同步锁Lock的实例)
- HTML5<q> 与 <blockquote> 的区别
- C# volatile与lock
- cssdisplay覆盖规律(css解决display:inline-block;产生的缝隙间隙的方法)
- sqlserver定时计划(sql server deadlock跟踪的4种实现方法)
- display:inline、block、inline-block 的区别
- RegisterClientScriptBlock与RegisterStartupScript区别
- css样式为什么要有空格(css几种解决inline-block间隙的方案整理)
- Sql Server 更新锁(UPDLOCK)
- 去除inline-block元素间的间隙
- 阴阳师 孟婆山兔CP不倒 新皮肤草稿 孟婆兔 让痒痒鼠点赞(阴阳师孟婆山兔CP不倒)
- 阴阳师孟婆御魂推荐 孟婆御魂搭配毕业套(阴阳师孟婆御魂推荐)
- 袁冰妍终于接到新剧,饰演反追男主,看到合作演员 眼光果然毒辣(袁冰妍终于接到新剧)
- 记忆中的台词(记忆中的台词)
- 袁冰妍轧戏 拍《琉璃》的同时还在拍《将夜》,难怪被骂演技差(拍琉璃的同时还在拍将夜)
- 刚红就耍大牌,《琉璃》角色滤镜碎一地,心疼工作人员(琉璃角色滤镜碎一地)
热门推荐
- Request获取URL的各种信息
- 如何用mysql建立图书管理系统(图书管理系统的sqlserver数据库设计示例)
- python编写端口扫描器(Python开发网站目录扫描器的实现)
- docker部署高性能服务器(Docker部署SQL Server 2019 Always On集群的实现)
- vue封装组件技巧(浅谈vue中所有的封装方式总结)
- python模块都是自己的语法(详解Python_shutil模块)
- 在sqlserver中如何看表格的类型(SQL Server 中的数据类型隐式转换问题)
- pythontkinter项目界面(python Tkinter版学生管理系统)
- php标签怎么写(php 使用mpdf实现指定字段配置字体样式的方法)
- python中if语句应学会什么(Python基础之条件控制操作示例if语句)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9