开发者

is this code thread safe?

开发者 https://www.devze.com 2023-03-27 03:55 出处:网络
I would like to know if this code is thread-safe and why if it\'s not the case. static IMyInterface _myinterface;

I would like to know if this code is thread-safe and why if it's not the case.

    static IMyInterface _myinterface;
        public static IMy开发者_Python百科Interface someStuff
        {
            get
            {
                if (_myinterface== null)
                {
                    _myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
                }

                return _myinterface;
            }
        }

Thanks!


As others have said, it is not. However, there are quite some options to make it thread safe appart from plain locking or the double checked pattern - which is not guaranteed to work on all (possible) implementations of the CLR.

Also note that unless you expect high contention, double checked locking is really not required and will hardly make a difference. It is relatively easy to get wrong (see the other (initially) wrong implementation in one of the answers as a great example).

See Jon Skeet's article on the subject for more information.


No. You need to use a lock.

private static readonly object m_lock = new object();
private static IMyInterface _myinterface;

public static IMyInterface someStuff
{
    get
    {
        lock(m_lock)
        {
           if (_myinterface == null)
           {
             //create instance
           }

           return _myinterface;
        }            
    }
}


For me, it's not. Because between the only way to be sure is to add a lock on it. It could possibly have two threads into the if statement !

http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=vs.80%29.aspx


No it isn't, you want to do something more like this. Notice the double check on the _myinterface==null. This is because after your first check, another thread may already be in the lock creating it. So you need to double check as soon as you reach your lock.

static IMyInterface _myinterface;
private static object lockObj = new object();
public static IMyInterface someStuff
{
   get
   {
      if (_myinterface== null)
      {
         lock(lockObj)
         {
            if (_myinterface== null)
            {             
                _myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
            }
         }
      }
      return _myinterface;
}


It isn't because there can be multiple initialization threads that would try to access the singleton at the same time.

This could work:

    static object _lock=new object(); 
    static IMyInterface _myinterface;
    public static IMyInterface someStuff
    {
        get
        {
            lock (_lock) {
                if (_myinterface== null)
                {
                    _myinterface= MyServiceLocator.GetCurrent().GetInstance<IMyInterface>();
                }
            }
            return _myinterface;
        }
    }


No, it's not.

Why?

Two calls come into someStuff one gets past if(_myInterface null) but is interrupted _myInterface = MYServiceLoc.... The second thread get's all the way in and completes before going to sleep. The second wakes up, assigns to _myInterface.

Both end up calling MyServiceLocator...GetInstance(), both assign to _myInterface, and both can return different values for _myInterface.


No, could happen that two different threads instantiate different instances and owerwrites previous saved value of the _myInterface.

Just imagine that Thread#1 entered if block

if (_myinterface== null)                 
{
 // ... here

and Thread#2 also reading _myinterface and entering this block too, in this time Thread#1 instantiated object and updated reference of _myinterface. But in the same time Thread#2 already cached value of _myinterface (it is NULL) and creating new one object and owerwriting value which was stored by Thread#1.

Wrap getter by lock() so only one thread can enter in (see an other answer regarding double lock)

0

精彩评论

暂无评论...
验证码 换一张
取 消