How can i resolve this reliability issue(Do not lock on objects with weak identity)?
Should i lock it with "object locker = new object();"?
lock (typeof(ObjectCultures))
{
if (!requestCache.Contains(GetCacheKey(objectId, cultureId)))
{
requestCache.Add(GetCacheKey(objectId, cultureId), responseStr);
}
}
Create a new static instance of an object and lock on that:
private static readonly object locker = new object();
lock (locker)
{
....
}
This is on the assumption you are locking inside a static method (due to your use of typeof(T) instead of the this which is also bad practice).
Obviously if you are inside an instance method remove the static from the declaration.
This article by Jon Skeet will help explain why the issue is being flagged in the first place.
You should lock an object not a type. Declare and instance this object in a main scope of your class, for sample:
public class SomeClass
{
private static readonly object _lock = new object();
public void SomeMethod()
{
lock (_lock)
{
// some code
}
}
}
This code will block all thread that are trying to execute this block and make them wait for finish and then execute the next thread.
Effectively, you need to put the lock in a static object reference. An object typed reference should be enough.
public class X
{
private readonly static _syncLock = new object();
public void DoStuff()
{
lock(_syncLock)
{
// Critical section
}
}
}
Exactly how you should lock.. depends on the context, and the bigger picture of code you are trying to write..
What you do want to avoid, is locking on objects of type indicated in the link you already got -
http://msdn.microsoft.com/en-us/library/ms182290.aspx
Do note that the handful of types listed here is not the full list...
• MarshalByRefObject
• ExecutionEngineException
• OutOfMemoryException
• StackOverflowException
• String
• MemberInfo
• ParameterInfo
• Thread
Full list would include instance of any type which is derived directly or indirectly from any of the above mentioned types..
Note that System.Type extends System.Reflection.MemberInfo
http://msdn.microsoft.com/en-us/library/system.type.aspx
And hence the warning, when using lock (typeof(ObjectCultures))
Related
I have two classes A & B. Both are calling each other and having their own locks. I am getting a deadlock in one particular scenario. Here is the sample code.
class A : Interface1, Interface2
{
private B _bInstance = new B();
private object _aSync = new object();
private static A Instance;
private A(){}
public GetInstance()
{
if (Instance == null) Instance = new A();
return Instance;
}
void Method1()
{
lock(_aSync)
{
_bInstance.Method1();
}
}
void WriteData()
{
lock (_aSync)
{
WriteToFile();
}
}
}
class B
{
private object _bSync = new object();
void Method1()
{
lock (_bSync)
{
// Have some code here which need to protect my
// member variables.
A.GetInstance.WriteData();
}
}
void OneSecondTimerEvent()
{
lock (_bSync)
{
// Have some code here which need to protect my
// member variables.
A.GetInstance.WriteData();
}
}
}
How do I synchronize the OneSecondTimerEvent(), if One second timer gets triggered When the A.Method1() is being executed?
Yes, your code shows canonical example of deadlock - 2 resources waiting for each other to continue.
To resolve you can:
manually order lock statements (i.e. B never takes additional locks if A already have lock),
scope locks to only internal state of each class and never nest locks. In this case sometimes you'd need to copy state to call external methods.
use other synchronization primitives/constructs that allow such nesting (i.e. Reader-Writer locks).
Rather than try and solve this particular deadlock issue (which btw, is a classic result of locking things in an inconsistent order), I would strongly advise designing a better relationship between A and B. The fact you had to use a static instance to achieve a circular dependency should be a big clue you've done something wrong. Perhaps A and B should reference a 3rd class C, which is solely responsible for locking and writing the data? (Although it's difficult to say without a bit more context).
I've been going through the singleton pattern, but I'm not understanding how the below code is thread safe:
public class ThreadSafeSingleton
{
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance
{
get { return Nested.instance; }
}
private class Nested
{
static Nested()
{
}
internal static readonly ThreadSafeSingleton instance = new ThreadSafeSingleton();
}
}
Why is this thread-safe?
The CLR executes static constructors only once. It is specified to do so. Therefore, instance is being initialized exactly once. That makes this thread-safe.
How the thread-safety is achieved is an implementation detail.
Please find below implementation for thread safe singleton implementation.
Also, you can use this question useful. It provides double locking thread safety which doesn't hurt performance.
Find reference for static here
Find the reference here
The below code is not thread-safe. Two different threads could both have evaluated the test if (instance==null) and found it to be true, then both create instances, which violates the singleton pattern. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.
Not thread safe singleton
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance=null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
Thread safe implementation:
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
This implementation is thread-safe. The thread takes out a lock on a shared object, and then checks whether or not the instance has been created before creating the instance. This takes care of the memory barrier issue (as locking makes sure that all reads occur logically after the lock acquire, and unlocking makes sure that all writes occur logically before the lock release) and ensures that only one thread will create an instance (as only one thread can be in that part of the code at a time - by the time the second thread enters it,the first thread will have created the instance, so the expression will evaluate to false). Unfortunately, performance suffers as a lock is acquired every time the instance is requested.
I have a class which has 3 static members. Each of static member is not thread-safe singleton.
I need to provide a thread safe implementation for their use.Is it ok?Or I need to provide thread-safe wrapper for each of them? If I should - how can I do it using Lazy<T>?
Additional question : Measure() and Do() of SingeltonClass1/2/3 are not thread-safe is func1() thread-safe?
public class MyLazySingleton
{
// static holder for instance, need to use lambda to construct since constructor private
private static readonly Lazy<MyLazySingleton> _instance
= new Lazy<MyLazySingleton>(() => new MyLazySingleton());
// private to prevent direct instantiation.
private MyLazySingleton()
{
s_c1 = SingletonClass1.Instance();
s_c2 = SingletonClass2.Instance();
s_c3 = SingletonClass3.Instance();
}
// accessor for instance
public static MyLazySingletonInstance
{
get
{
return _instance.Value;
}
}
public void func1()
{
if (s_s1.Measure() || s_c2.Measure())
{
c_c3.Do();
}
}
static SingletonClass1 s_c1 = null;
static SingletonClass1 s_c2 = null;
static SingletonClass1 s_c3 = null;
}
How should I re-implement MyLazySingleton if its constructor should get 2 arguments? string str and int i
I have asked a follow up question Thread-safe methods in the singleton class
It's thread-safe as it is.
The default value for Lazy<T>'s LazyThreadSafetyMode is ExecutionAndPublication.
From the MSDN page on the new Lazy<T>(Func<T>) constructor:
An instance that is created with this constructor may be used
concurrently from multiple threads.
The thread safety mode of a Lazy instance that is initialized with
this constructor is LazyThreadSafetyMode.ExecutionAndPublication.
If you were to use another overload where you could pass a different LazyThreadSafetyMode value it wouldn't be thread safe. But using the constructor as you are now, it is thread safe.
EDIT: Regarding your additional edited question, if those methods on your SingletonClass1 type are not thread safe: then no, func1 is not thread safe either.
From the Lazy<T> MSDN Page:
Making the Lazy object thread safe does not protect the lazily
initialized object. If multiple threads can access the lazily
initialized object, you must make its properties and methods safe for
multithreaded access.
You will need to make sure that those methods/interactions between those classes are thread safe. This might be as simple as wrapping the func1 body with a lock statement, but I can't say for certain depending on how your 3 instances of SingletonClass1 interact with each other or how calling code may access them.
To ensure Thread-safety you have to set the LazyThreadSafetyMode parameter of the Lazy<T> constructor. There are 3 available values:
None: not thread-safe
PublicationOnly: many MyLazySingleton instance may be created, but only one will be published/returned by the Value property. Internally it uses Interlocked.CompareExchange
ExecutionAndPublication: The value is create only once
Here's an example:
new Lazy<Test>(() => new Test(), LazyThreadSafetyMode.ExecutionAndPublication)
I have problem with the initialization of the static member of a static class. As far as I know, it will be initialized one time only, so I lock this variable when I do fooList.Add(...) in concurrency, to ensure this operation is thread safe:
internal static class ObjectA
{
private static object _lockAdd = new object();
public void functionA()
{
lock (_lockAdd)
{...
I encountered some weird situations, so I decided to write the hashcode of _lockAdd by log4net, and to my surprise this is what I observed:
【INFO】【2012-04-20 15:26:44,080】【thread12】
_lockAdd's hashcode (51755728)...
【INFO】【2012-04-20 15:26:58,624】【thread16】
_lockAdd's hashcode (31071611)...
As you see, the two '_lockAdd ' addresses are different, why is it, or is my understanding of static members wrong ? And how should i do to ensure thread safety when the operation is in a static class?
sorry for the fake code's error, this is my actual code:
internal static class UtilExtension
{
private static object _lockAdd = new object(); //initial twice ? why?
public static void DoAdd(this Type entityType)
{
if (!Pools.Has(entityType))
{
lock (_lockAdd)
{
if (!Pools.Has(entityType)) //insure operation below is thread safe
{
// i find something wrong in concurrency,so i log the _lockAdd's hashcode,
// and then i found it's hashcode is different( in my opinion, it means not the same variables )
LogUtil.Info(_lockAdd.GetHashCode().ToString());
//... do fooList.Add(...)
}
}
}
}
}
For an object only used for locking, use readonly:
private static readonly object _lockAdd = new object();
If the object was getting overwritten somehow, you'll most probably get different results from either the compiler or runtime next time you start the application.
Maybe i make it complicated, the truth is that,the static member is thread unsafe always。So when we use a static member(_lockAdd) as a lock target, we should add readonly to insure the _lockAdd is initilize only once.
What is the difference (if any) between using
void MethodName()
{
lock(this)
{
// (...)
}
}
or
private object o = new object();
void MethodName()
{
lock(o)
{
// (...)
}
}
?
Is there a difference in performance? Style? Behaviour?
lock(this) will lock on the "current" object.
Locking on "this" is usually a bad idea as it exposes the lock to other code; I prefer to have a readonly field, like this:
public class Foo
{
private readonly object padlock = new object();
public void SomeMethod()
{
lock(padlock)
{
...
}
}
}
That way all calls to SomeMethod (and anything else in Foo which locks on padlock) will lock on the same monitor for the same instance of Foo, but nothing else can interfere by locking on that monitor.
In reality, unless you're dealing with "rogue" code, it's unlikely that other code will actually lock on the reference to an instance of Foo, but it's a matter of encapsulation.
The difference is that anyone can lock on your instance, but only you can lock on a private object.
This helps prevent deadlocks.
For example:
Let's say that Microsoft used lock(this) in the Control class.
Then, if someone else locks on a Control instance, his lock would prevent the code in Control from running, which is not what he wants.
This is particularly bad if you lock on types that are shared across AppDomains
The pattern I usually follow is this, for a class declared static....
public static class SomeClass{
private static object objLock = new object();
....
public static object SomeProperty{
get{
lock(objLock){
// Do whatever needs to be done
}
}
set{
lock(objLock){
}
}
}
}
Likewise for a normal class I would follow this pattern:
public class SomeClass{
private readonly object objLock = new object();
....
public object SomeProperty{
get{
lock(objLock){
// Do whatever needs to be done
}
}
set{
lock(objLock){
}
}
}
}
In that way, no one can lock on my instance and will prevent deadlocks from occuring...
Edit: I have amended this article to make it clearer with regards to the code where the basis of the static lock would be used and for a normal class... Thanks Steven and Dalle for their point outs...
There is a difference in scope and there can be a difference in behavior
(incidentally, using "this" is not recommended by MS
// in this case, your lock object is public, so classes outside of this can lock on the same thing
lock(this) {}
// in this case, your lock is private, and only you can issue a lock statement against it
private object lockobj = new object()
..
lock(this.lockobj) {}
// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion
void SomeMethod()
{
// using a local variable for a lock -- wrong
object obj = new object();
lock(obj) {}
}