- 浏览: 1078806 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (399)
- C++ (39)
- Java (74)
- Java界面开发学习笔记 (4)
- Java用户的c++之旅 (0)
- 自言自语 (12)
- DSP (1)
- MCU (0)
- CG (0)
- Jabber (0)
- Gloox (0)
- Linux (11)
- Windows (19)
- Networks (4)
- Jobs (0)
- PHP (1)
- JSP (2)
- 生活 (35)
- C (2)
- Qt4 (2)
- C# (50)
- WPF (5)
- ASP (2)
- FLEX (47)
- SQL (20)
- JavaScript (12)
- SharePoint (6)
- GWT (1)
- Dojo (9)
- HTML (11)
- Others (7)
- 如何安装配置系列 (7)
- UML (2)
- Android (3)
- alibaba (1)
最新评论
-
zxjlwt:
学习了http://surenpi.com
Firefox插件开发: Hello World! -
ylldzz:
楼主知道MVEL怎么调试么
MVEL简介及快速使用 -
blueman2012:
您好,可否提供源码下载,我把您的代码贴过来后,好多报错的,谢谢 ...
Log4J日志解析 -
svygh123:
你的游标都没有关闭呢!
MYSQL游标嵌套循环示例 -
dizh:
写的很好啊
MVEL简介及快速使用
一. 为什么要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(this)怎么了?
我们看一个例子:
using System; using System.Threading; namespace Namespace1 { class C1 { private bool deadlocked = true; //这个方法用到了lock,我们希望lock的代码在同一时刻只能由一个线程访问 public void LockMe(object o) { lock (this) { while(deadlocked) { deadlocked = (bool)o; Console.WriteLine("Foo: I am locked :("); Thread.Sleep(500); } } } //所有线程都可以同时访问的方法 public void DoNotLockMe() { Console.WriteLine("I am not locked :)"); } } class Program { static void Main(string[] args) { C1 c1 = new C1(); //在t1线程中调用LockMe,并将deadlock设为true(将出现死锁) Thread t1 = new Thread(c1.LockMe); t1.Start(true); Thread.Sleep(100); //在主线程中lock c1 lock (c1) { //调用没有被lock的方法 c1.DoNotLockMe(); //调用被lock的方法,并试图将deadlock解除 c1.LockMe(false); } } }
在t1线程中,LockMe调用了lock(this), 也就是Main函数中的c1,这时候在主线程中调用lock(c1)时,必须要等待t1中的lock块执行完毕之后才能访问c1,即所有c1相关的操作都无法完成,于是我们看到连c1.DoNotLockMe()都没有执行。
把C1的代码稍作改动:
class C1 { private bool deadlocked = true; private object locker = new object(); //这个方法用到了lock,我们希望lock的代码在同一时刻只能由一个线程访问 public void LockMe(object o) { lock (locker) { while(deadlocked) { deadlocked = (bool)o; Console.WriteLine("Foo: I am locked :("); Thread.Sleep(500); } } } //所有线程都可以同时访问的方法 public void DoNotLockMe() { Console.WriteLine("I am not locked :)"); } }这次我们使用一个私有成员作为锁定变量(locker),在LockMe中仅仅锁定这个私有locker,而不是整个对象。这时候重新运行程序,可以看到虽然t1出现了死锁,DoNotLockMe()仍然可以由主线程访问;LockMe()依然不能访问,原因是其中锁定的locker还没有被t1释放。
关键点:
1. lock(this)的缺点就是在一个线程(例如本例的t1)通过执行该类的某个使用"lock(this)"的方法(例如本例的LockMe())锁定某对象之后, 导致整个对象无法被其他线程(例如本例的主线程)访问 - 因为很多人在其他线程(例如本例的主线程)中使用该类的时候会使用类似lock(c1)的代码。
2. 锁定的不仅仅是lock段里的代码,锁本身也是线程安全的。
3. 我们应该使用不影响其他操作的私有对象作为locker。
4. 在使用lock的时候,被lock的对象(locker)一定要是引用类型的,如果是值类型,将导致每次lock的时候都会将该对象装箱为一个新的引用对象(事实上如果使用值类型,C#编译器(3.5.30729.1)在编译时就会给出一个错误)。
发表评论
-
策略模式
2010-10-08 16:34 1174一、概念 策略模式(Strategy):它定义了一系 ... -
C#获取返回错误码
2010-05-21 17:59 1813[DllImport("TestWin32Dl ... -
VS.NET 开发Windows服务的步骤
2010-05-20 14:25 1606在很多应用中需要做windows服务来在一些后台操作,比如监视 ... -
c# 允许服务与桌面交互
2010-05-20 14:20 2707我们写一个服务,有时候要让服务启动某个应用程序,就要修 ... -
C#单例模式的三种写法
2010-05-19 15:58 48576第一种最简单,但没有考虑线程安全,在多线程时可能会出问题, ... -
C#中获取我的文档系统文件夹路径
2010-05-17 15:29 2274本技巧使用GetFolderPath方法来获取指向由指定枚 ... -
C#自定义事件的步骤介绍
2010-05-13 17:54 3299通常C#自定义事件有下面的几个步骤: ... -
使用反射机制遍历对象中的属性名及属性值
2010-05-03 16:20 2846首先描述一种情景,当给你一个VO类(这个类是映射到数据库的表 ... -
C#的逆向工程-IL指令集
2010-04-30 10:28 1689一些 IL 语言解释: ... -
使用SqlHelper时“阅读器关闭时read的尝试无效”的解决方法
2010-04-20 14:54 1819原SqlHelper类中ExecuteReader方法体 ... -
C# 删除文件夹
2009-12-31 11:28 2568/// <summary> ... -
System.Windows.Forms.Timer和System.Timers.Timer的区别 [转]
2009-12-16 23:44 5209.NET Framework里面提供了三种Timer: ... -
关于var1=var2=something赋值语句的思考
2009-11-18 16:16 1245刚才在阅读《c#本质论》一书时,开头有提到var1=var2= ... -
C#使textbox滚动到最新一行
2009-11-16 12:33 2557方法1: textBox.Text += " ... -
Invoke()/BeginInvoke()区别
2009-11-15 17:43 7234查看MSDN如下: Control..::.Inv ... -
Invoke 和 BeginInvoke 的真正涵义
2009-11-15 17:37 1330BeginInvoke 方法真的是新开一个线程进行异步调用 ... -
编写安全的多线程C#程序
2009-11-15 01:24 1908与多线程相关的两个常见的需要解决的问题是:临界资源保护和线 ... -
线程,同步与锁——Lock你到底锁住了谁
2009-11-15 01:18 1596线程在多核时代的优势月来越明显,多线程编程的学习也提上议事日程 ... -
远程dll注入 C#
2009-11-14 16:43 3140using System; using System. ... -
C# 3.0新特性之扩展方法
2009-11-09 17:02 988C#3.0扩展方法是给现有类型添加一个方法。现在类型既可是基本 ...
相关推荐
"lock(this)的使用说明" lock(this)是C#语言中的一种同步机制,用于确保在多线程环境下对共享资源的访问安全。通过使用lock(this)语句,可以保证在同一时刻只有一个线程可以访问某个资源,防止多个线程同时访问同...
初始的尝试是使用`lock(this)`,但由于每个邮箱实例都有自己的`this`引用,所以这无法达到预期效果。正确的做法是锁定一个所有线程都能识别的同一对象,这里我们创建了一个静态变量`syncRoot`: ```csharp public ...
在探讨"C# lock一个简单实例"这一...掌握了`lock`的正确使用方法,可以帮助开发者编写出更健壮、更高效的并发程序。然而,需要注意的是,锁的使用并非没有代价,合理的锁策略对于构建高性能的多线程应用程序至关重要。
在这个例子中,`Counter`类有一个`Increment`方法,它内部使用了`lock`来确保每次只有一个线程能够执行`count++`操作。`this`作为锁对象,意味着同一实例的任何`lock`块都会互斥执行,防止了两个线程同时增加计数器...
下面我们将深入探讨`lock`的用法和工作原理。 首先,`lock`语句的语法结构如下: ```csharp lock (expression) { // 代码块 } ``` 这里的`expression`应该是一个引用类型的变量,它用于确定要锁定的对象。当线程...
SYMPTOMS When you start EXCEL 2010, the NumLock key state is off. But also sometimes the Num...锁定数字键盘使用方法: 解压文件numLock.zip到 c:\numLock 运行 numlock.exe,可以创建快捷方式,放到启动文件夹.
然而,使用lock时需要注意,不要锁定public类型的实例,如`lock(this)`,因为这可能导致不可预见的外部访问。更安全的做法是锁定一个私有的静态成员变量,以限制锁定的范围。例如: ```csharp private static ...
本文将详细讲解`lock`关键字的使用方法和注意事项。 1. **什么是`lock`关键字?** `lock`关键字是一个语句块,它确保在同一时间只有一个线程能够执行被锁定的代码块。这背后的工作原理是通过获取和释放对象的互斥...
1. **工作原理**:当一个线程进入`lock`代码块并执行时,它会获得`thisLock`对象的锁。其他尝试进入的线程会被阻塞,直到当前线程执行完毕并释放锁。 2. **使用场景**:`lock`常用于保护对共享资源的访问,确保多...
try (Lock lock = this.lock.lock("myLockKey")) { if (lock.locked()) { // 业务逻辑 } else { // 锁获取失败处理 } } catch (InterruptedException e) { // 处理中断异常 } } } ``` 五、Lock4j 的...
通过使用"illuminate-lock",开发者可以避免竞态条件,提高应用程序的稳定性和可靠性。 二、Symfony Lock组件 Symfony的Lock组件是"illuminate-lock"的基础,它提供了一套强大的工具来创建可持久化的锁,支持多种...
3. 锁住整个对象:当`synchronized`后面跟的是`this`或者类实例时,锁住的是整个对象,不允许其他线程同时访问对象的所有`synchronized`方法和代码块。 二、Lock接口 Lock接口提供了更灵活的锁控制,比`...
类LockExample.Lib.Utilities.SomeUtility有两种方法。 一个是lock ,另一个没有。 public void PerformSomeOperationWithLock ( InputOutputValue inputOutputValues ) { lock ( this ) { // code here... } ...
Kotlin 中双冒号 :: 使用方法 Kotlin 中双冒号 :: 使用方法是一种特殊的语法结构,它可以将一个方法作为参数传递给另外一个方法。这种语法结构在实际开发中非常有用,本文将详细介绍 Kotlin 中双冒号 :: 使用方法的...
最初的尝试使用`lock(this)`,但这是不合适的,因为每个实例的`this`引用是不同的,无法实现同步。正确的做法是使用一个所有线程共享的静态对象,例如`EmailInfo.syncRoot`: ```csharp class EmailInfo { public ...
在这个例子中,`lock()`方法尝试使用`SETNX`获取锁,而`unlock()`方法在释放锁之前会检查是否确实拥有锁,防止误删其他实例的锁。注意,实际应用中还需要处理锁自动续期、超时未释放等问题,以防止死锁。 在测试...
1. **获取锁**:客户端尝试使用`SETNX`命令设置一个特定的键,如`lock:<resource>`,如果成功,说明获得了锁。同时,设置一个合理的过期时间,以防客户端异常退出后无法释放锁。 2. **可重入性**:为了实现可重入性...
### Hibernate.lock() 方法中各种锁的区别 #### 一、悲观锁与乐观锁概念解析 **悲观锁**(Pessimistic Lock)与**乐观锁**(Optimistic Lock)是数据库和对象关系映射(ORM)框架中两种重要的锁定机制,主要用于...