C#延迟初始化和放大器;&安培;比赛到初始化? [英] C# Lazy Initialization && Race-to-initialize?

查看:141
本文介绍了C#延迟初始化和放大器;&安培;比赛到初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在<一个href="http://books.google.co.il/books?id=t1de8nSVYnkC&pg=PA906&lpg=PA906&dq=%22LazyInitializer.EnsureInitialized%20%28ref%20_expensive,%22&source=bl&ots=24qfWwIk7y&sig=9ygi5-TUZEWf1LD0-KKPUbVVrQo&hl=en&sa=X&ei=XLUHUMDuCeLP0QXRppHvBA&redir_esc=y#v=onepage&q=%22LazyInitializer.EnsureInitialized%20%28ref%20_expensive,%22&f=false"相对=nofollow>阅读有关 LazyInitializer ,它是:

它提供的初始化的另一种方式,有多个线程   比赛进行初始化。

It offers another mode of initialization that has multiple threads race to initialize.

下面是一个例子:

Expensive _expensive;
public Expensive Expensive
     {
       get // Implement double-checked locking
         {
           LazyInitializer.EnsureInitialized (ref _expensive,() => new Expensive());
           return _expensive;
         }
     }

问题1

看:

looking at :

为什么#A说,它的器具双重检查锁定?它只是一个get proeprty?

why #A says its implements double-checking locking ? it is just a get proeprty ?

问题#2

请问#B(拉姆达EX pression)是线程安全的?

Does #B (lambda expression) is thread safe ?

问题3

所以,我通过看一个示例搜索关于此的比赛到初始化的事情:

So i searched about this "race-to-initialize" thing by looking at a sample:

volatile Expensive _expensive;
public Expensive Expensive
{
  get
  {
    if (_expensive == null)
    {
      var instance = new Expensive();
      Interlocked.CompareExchange (ref _expensive, instance, null);
    }
    return _expensive;
  }
}

然后我想到了:心不是比赛进行到初始化是线程安全的。

and then i thought about : isnt race to initialize is thread safe ?

E /克/如果2个线程进入:

e/g/ if 2 threads get into :

昂贵的对象将被创建两次!

the expensive object will be created twice !

所以,再一次,3个问题

So again , 3 question

1)为什么#A说,它的器具双重检查锁定?它只是一个get proeprty?

1)why #A says its implements double-checking locking ? it is just a get proeprty ?

2)是否#B(拉姆达EX pression)是线程安全的?

2)Does #B (lambda expression) is thread safe ?

3)心不是种族初始化是线程安全的。

3)isnt race to initialize is thread safe

推荐答案

EnsureInitialized 的各种重载。一些接受的SyncLock 对象(可以是,并将由 EnsureInitialized <创建/ code>法)。人无我有一个的SyncLock 作为参数。所有 EnsureInitialized 的保证,如果被称为在同一时间两个(或更多),而对象是未初始化的不同的线程,这两个线程将收到回一个引用同一个对象。所以:

There are various overloads of EnsureInitialized. Some accepts a synclock object (that can be null and will be created by the EnsureInitialized method). Others don't have a synclock as a parameter. All the EnsureInitialized guarantee that if called at the same time by two (or more) different threads while the object is uninitialized, the two threads will receive back a reference to the same object. So:

Expensive _expensive;

// On thread 1
LazyInitializer.EnsureInitialized (ref _expensive,() => new Expensive());

// On thread 2
LazyInitializer.EnsureInitialized (ref _expensive,() => new Expensive());

_expensive 对象将由两个线程中可以看出将是相同的。

the _expensive object that will be seen by the two threads will be the same.

唯一的问题是,新贵()可以被称为两次(每个线程一次,所以在多线程的比赛也可以被称为甚至更多次。)

The only problem is that new Expensive() could be called twice (once per thread, so in a multi-thread race it could be called even more times.)

如果你不想要它,使用的SyncLock 过载:

If you don't want it, use the synclock overload:

Expensive _expensive;
object _sync = null;
bool _useless;

// On thread 1
LazyInitializer.EnsureInitialized (ref _expensive, ref useless, ref _sync, () => new Expensive());

// On thread 2
LazyInitializer.EnsureInitialized (ref _expensive, ref useless, ref _sync, () => new Expensive());

现在的新贵()将被调用一次,两个(或更多)的线程运行的每一个可能的组合。

Now the new Expensive() will be called only once, for every possible combination of the two (or more) threads running.

这篇关于C#延迟初始化和放大器;&安培;比赛到初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆