C# 使用lock关键字lock不同的对象
2015-11-04 15:40
826 查看
c# lock关键字的本质
是调用Monitor.Enter(object obj)并且在finally的时候调用Monitor.Exit(obj)
在obj是不同数据类型的时候会出现不同的情况
1.锁定类型 例如lock(typeof(int)) lock(typeof(ClassA)) // CalssA 是一个类的定义
备注:前者作用范围跨AppDomain 不跨Process, 后者不跨AppDomain(默认设置)
使用范围:绝不推荐使用
2.锁定字符串 例如lock("abc") 和lock(s)//s是一个字符串的实例变量
备注:当字符串已经驻留在内存的时候 这个lock是有效的, 如果字符串未驻留在内存那么这个lock就失效了,该lock是跨Appdomain不跨Process
使用范围: 一般不推荐使用
以下代码显示了非驻留字符串导致的无法lock的问题,请在实际应用中避免lock(a+b)即使他们的值一样 (vs2008 Debug)
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
publicclass ClassA
{
publicvoid Test()
{
lock (this)
{
Console.WriteLine("Test Begin Lock");
Thread.Sleep(10000);
Console.WriteLine("Test End Lock");
}
}
}
class Program
{
staticvoid Main(string[] args)
{
ClassA classA =new ClassA();
ThreadPool.QueueUserWorkItem(p =>
{
Thread.Sleep(3000); Console.WriteLine(" Thread2 Begin Test");
lock (classA)
{
Console.WriteLine("Thread2 Begin Lock");
Thread.Sleep(1000);
Console.WriteLine("Thread2 End Lock");
}
});
classA.Test();
Console.ReadLine();
}
}
}
7. lock(null) 必然抛出一个异常
8.推荐使用以下方法lock
private static object asyncLock=new object();
lock(asyncLock)
使用 private object asyncLock=new object(); 也是ok的,但是请注意避免之前提到的WebPage每次new一个类导致lock失效的问题
影响范围不跨AppDomain
PS1:关于跨不跨AppDomain的问题,其实用处不大,大部分应用程序都只是创建一个DefaultDomain
PS2:可以将一些Assembly设置为跨AppDomain的,以减少内存浪费和提高性能, 例如string和一些基本类型都是这样实现的
PS3:本人水平有限,如果错漏还请大家帮忙...
是调用Monitor.Enter(object obj)并且在finally的时候调用Monitor.Exit(obj)
在obj是不同数据类型的时候会出现不同的情况
1.锁定类型 例如lock(typeof(int)) lock(typeof(ClassA)) // CalssA 是一个类的定义
备注:前者作用范围跨AppDomain 不跨Process, 后者不跨AppDomain(默认设置)
使用范围:绝不推荐使用
2.锁定字符串 例如lock("abc") 和lock(s)//s是一个字符串的实例变量
备注:当字符串已经驻留在内存的时候 这个lock是有效的, 如果字符串未驻留在内存那么这个lock就失效了,该lock是跨Appdomain不跨Process
使用范围: 一般不推荐使用
以下代码显示了非驻留字符串导致的无法lock的问题,请在实际应用中避免lock(a+b)即使他们的值一样 (vs2008 Debug)
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
publicclass ClassA
{
publicvoid Test()
{
lock (this)
{
Console.WriteLine("Test Begin Lock");
Thread.Sleep(10000);
Console.WriteLine("Test End Lock");
}
}
}
class Program
{
staticvoid Main(string[] args)
{
ClassA classA =new ClassA();
ThreadPool.QueueUserWorkItem(p =>
{
Thread.Sleep(3000); Console.WriteLine(" Thread2 Begin Test");
lock (classA)
{
Console.WriteLine("Thread2 Begin Lock");
Thread.Sleep(1000);
Console.WriteLine("Thread2 End Lock");
}
});
classA.Test();
Console.ReadLine();
}
}
}
7. lock(null) 必然抛出一个异常
8.推荐使用以下方法lock
private static object asyncLock=new object();
lock(asyncLock)
使用 private object asyncLock=new object(); 也是ok的,但是请注意避免之前提到的WebPage每次new一个类导致lock失效的问题
影响范围不跨AppDomain
PS1:关于跨不跨AppDomain的问题,其实用处不大,大部分应用程序都只是创建一个DefaultDomain
PS2:可以将一些Assembly设置为跨AppDomain的,以减少内存浪费和提高性能, 例如string和一些基本类型都是这样实现的
PS3:本人水平有限,如果错漏还请大家帮忙...
相关文章推荐
- C# 委托delegate 例子
- C# greedy snake source code
- (c#)不同窗体间传值
- AutoCAD.Net/C#.Net QQ群:193522571 AutoCAD向命令栏发送命令
- AutoCAD.Net/C#.Net QQ群:193522571 AutoCAD中状态栏
- C# Tast 随笔
- C# DEBUG 调试信息打印及输出详解
- 2015-11-04 报表(c#部分)(Datatable 查询,弹出日期控件,输入是否整数)
- c#写windows服务
- C#占位符和格式化字符串
- C# 委托实例(跨窗体操作控件)
- C#实现程序的版本升级更新
- C#中通过Selenium定位<a>标签的问题
- C# WinFrom 去掉groupbox的边框
- c# 换行符
- c# WinForm 创建与读写配置文件
- C# 索引器
- [C# 线程处理系列]专题三:线程池中的工作者线程
- VS2010 C# Activex
- .Net项目实战2管理员界面充值的功能