【C#】lock语句及在单例模式中应用
来源:互联网 发布:软件架构 pdf 编辑:程序博客网 时间:2024/06/06 03:55
C#中的lock语句是怎么回事,有什么作用?
C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。
注意的地方有:lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是private static readonly 或者private static。常见的lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 都是不合理的写法。
原因:
1.lock(this),主要问题是如果类为实例化类,那么this也只是当前实例,不能起到锁定的作用,而且即使是静态类可以被锁定,那么由于尺寸问题,不如锁定不可变小对象合算。
2.lock(typeof())问题在于锁定对象类型当相于锁定类型中的静态对象部分,锁定了所有实例,速度慢;另一方面,有可能程序其他部分在访问该对象,已经替您锁定,将导致您锁定语句的挂起。原文(Here's why: Since there's one type object for all instances of a class, it would appear that locking it would provide a lock equivalent to locking a static object contained in your class. You would lock all instances of the class, wait until other threads were done accessing any part of any instance, then lock access so you could access static members safely and without another thread interfering.)
3.lock("")问题在于微软将内容相同的字符串视为同一个对象,如果您在此锁定了他,那么其实是锁定了同一个对象,将阻止其他地方对字符串的锁定。
lock语句的一个典型应用就是单例模式。 而单例模式的一个最简单实现方式就是用静态对象方式。如下:
1234567public
class
ABicycle {
private
static
ABicycle aBicycle =
new
ABicycle();
public
ABicycle Instance()
{
return
aBicycle;
}
}
这是实现单例模式最简单的一种方式,但是有一个缺点就是假如ABicycle类被提前调用后,aBicycle即被实例化,没法做到实例化延迟。在此情况下,利用一个关联类可以避免此问题的发生。即:
12345678910111213public
class
ABicycle {
public
ABicycle Instance()
{
return
ABicycleStance.Instance();
}
}
private
class
ABicycleStance {
internal
static
readonly
ABicycle aBicycle =
new
ABicycle();
public
ABicycle Instance()
{
return
aBicycle;
}
}
单例模式的一个思路是利用C#的lock语句实现。 最简单实现方式为:
1if
(... ==
null
){ ... =
new
... }
return
...;
如果这样实现,有一个问题无法回避,即无法确保只能让一个线程使对象实例化,因为有可能多个线程并发执行到此,同时实例化了对象。为此,需要引用lock语句。引用的方式也有讲究,最直接的实现方式就是:
12345678910111213private
static
readonly
locker =
new
object
();
//或者这样写也可以。
//private static locker = new object();
lock
(locker)
{
if
(.. ==
null
)
{
...
}
}
上面做法可行,但是有一个问题是每次返回时首先要对locker上锁,这样就牺牲了一些本来不必牺牲的性能,因此,可以修改为以下做法:
123456789101112private
static
readonly
locker =
new
object
();
if
(.. ==
null
)
{
lock
(locker)
{
if
(... ==
null
)
{
}
}
}
这样,对于多线程来说是安全的,而且不必每次加锁,只有在判断对象没有实例化时加锁,避免了性能上的损失。
附上C#的一个模板父类
using UnityEngine;using System.Collections;public class Singleton<T> where T : class, new(){ private static T _instance; private static readonly object syslock = new object(); public static T Instance { get { if (_instance == null) { lock (syslock) { if (_instance == null) { _instance = new T(); } } } return _instance; } }}
参考资料:
http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
http://hi.baidu.com/benzhan/item/6304481419d6360dd1d66dff
http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects
原文链接:www.cnblogs.com/jizhong
C#中的lock语句是怎么回事,有什么作用?
C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。
注意的地方有:lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是private static readonly 或者private static。常见的lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 都是不合理的写法。
原因:
1.lock(this),主要问题是如果类为实例化类,那么this也只是当前实例,不能起到锁定的作用,而且即使是静态类可以被锁定,那么由于尺寸问题,不如锁定不可变小对象合算。
2.lock(typeof())问题在于锁定对象类型当相于锁定类型中的静态对象部分,锁定了所有实例,速度慢;另一方面,有可能程序其他部分在访问该对象,已经替您锁定,将导致您锁定语句的挂起。原文(Here's why: Since there's one type object for all instances of a class, it would appear that locking it would provide a lock equivalent to locking a static object contained in your class. You would lock all instances of the class, wait until other threads were done accessing any part of any instance, then lock access so you could access static members safely and without another thread interfering.)
3.lock("")问题在于微软将内容相同的字符串视为同一个对象,如果您在此锁定了他,那么其实是锁定了同一个对象,将阻止其他地方对字符串的锁定。
lock语句的一个典型应用就是单例模式。 而单例模式的一个最简单实现方式就是用静态对象方式。如下:
public
class
ABicycle {
private
static
ABicycle aBicycle =
new
ABicycle();
public
ABicycle Instance()
{
return
aBicycle;
}
}
这是实现单例模式最简单的一种方式,但是有一个缺点就是假如ABicycle类被提前调用后,aBicycle即被实例化,没法做到实例化延迟。在此情况下,利用一个关联类可以避免此问题的发生。即:
public
class
ABicycle {
public
ABicycle Instance()
{
return
ABicycleStance.Instance();
}
}
private
class
ABicycleStance {
internal
static
readonly
ABicycle aBicycle =
new
ABicycle();
public
ABicycle Instance()
{
return
aBicycle;
}
}
单例模式的一个思路是利用C#的lock语句实现。 最简单实现方式为:
if
(... ==
null
){ ... =
new
... }
return
...;
如果这样实现,有一个问题无法回避,即无法确保只能让一个线程使对象实例化,因为有可能多个线程并发执行到此,同时实例化了对象。为此,需要引用lock语句。引用的方式也有讲究,最直接的实现方式就是:
private
static
readonly
locker =
new
object
();
//或者这样写也可以。
//private static locker = new object();
lock
(locker)
{
if
(.. ==
null
)
{
...
}
}
上面做法可行,但是有一个问题是每次返回时首先要对locker上锁,这样就牺牲了一些本来不必牺牲的性能,因此,可以修改为以下做法:
private
static
readonly
locker =
new
object
();
if
(.. ==
null
)
{
lock
(locker)
{
if
(... ==
null
)
{
}
}
}
这样,对于多线程来说是安全的,而且不必每次加锁,只有在判断对象没有实例化时加锁,避免了性能上的损失。
附上C#的一个模板父类
using UnityEngine;using System.Collections;public class Singleton<T> where T : class, new(){ private static T _instance; private static readonly object syslock = new object(); public static T Instance { get { if (_instance == null) { lock (syslock) { if (_instance == null) { _instance = new T(); } } } return _instance; } }}
参考资料:
http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
http://hi.baidu.com/benzhan/item/6304481419d6360dd1d66dff
http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects
原文链接:www.cnblogs.com/jizhong
- c#lock语句及在单例模式中应用
- 【C#】lock语句及在单例模式中应用
- 单例模式应用场景及实现(By C++)
- [C++]单例模式应用
- java 单例模式及在SSH框架中运用
- java 单例模式例子及应用
- PHP单例模式及应用实例
- 单例模式--介绍、应用及代码
- 单例模式及应用简析
- 单例设计模式及应用
- 单例模式在DRP中的应用
- 单例模式在JAVA中的应用
- 单例模式在Unity中的应用
- 单例模式在android中的应用
- 单例模式在spring的应用
- 单例模式在Unity中的应用
- 单例模式在Android中的应用
- 单例模式在数据库中的应用
- C语言中内存分配
- Object-C基础(5)——指针
- 自主开发linux下的WeChat(含图形界面)
- 【框架篇】mvc、mvp、mvvm使用关系总结
- 【Educational Codeforces Round 10D】【树状数组】Nested Segments 每条线段内部有多少条线段
- 【C#】lock语句及在单例模式中应用
- Python基础--多线程
- 关于Dovecot 与 mysql 安装的一场巨汗。
- Vmware启动虚拟机时显示“内部错误”
- bzoj 2631 tree
- JVM中的垃圾收集器
- 修改linux下mysql的编码
- 使用Anaconda2 和 Pycharm搭建Python IDE
- 用C#在windows上操控电脑自带蓝牙(入道指南)