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).
Related
In an application that I am developing I will be using 2 threads to do various operations. (I will not go into detail here.) These threads work in loops, checking if there is work to be done, doing work, calculating the time they need to wait and waiting. (See below)
public Global : System.Web.HttpApplication
{
private static Thread StartingDateThread;
private static Thread DeadlineDateThread;
private static object o1;
private static object o2;
public static Thread GetStartingDateThreadInstance
{
get
{
if(StartingDateThread==null)
{
StartingDateThread=new Thread(new ThreadStart(MonitorStartingDates));
}
return StartingDateThread;
}
}
public static Thread GetDeadlineThreadInstance
{
get
{
if(DeadlineDateThread==null)
{
DeadlineDateThread=new Thread(new ThreadStart(MonitorDeadlines));
}
return DeadlineDateThread;
}
}
public static object GetFirstObjectInstance
{
get
{
if(o1==null)
{
o1=new object();
}
return o1;
}
}
public static object GetSecondObjectInstance
{
get
{
if(o2==null)
{
o2=new object();
}
return o2;
}
}
protected void Application_Start(object sender, EventArgs e)
{
GetStartingDateThreadInstance.Start();
GetDeadlineThreadInstance.Start();
//////////////////////
////Do other stuff.
}
public void MonitorStartingDates()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetFirstObjectInstance);
}
else
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(new TimeSpan(12, 0, 0));
Monitor.Exit(GetFirstObjectInstance);
}
}
}
public void MonitorDeadlines()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 3 days and 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetSecondObjectInstance);
}
else
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(new TimeSpan(3, 12, 0, 0));
Monitor.Exit(GetSecondObjectInstance);
}
}
}
As you can see these two threads are started in the Application_Start method in the asax file. They operate if there is stuff available to do and then they calculate the time period they need to wait and then they wait. However, as users of the web application do operations new records will be inserted into the database and there will be circumstances where any of the two threads will have to resume operation sooner than planned. So, say I have a method in my DataAccess class which inserts into the database new data. (See below)
public class DataAccess
{
///////////////
//
public void InsertNewAuction()
{
///Insert new row calculate the time
Monitor.Pulse(Global.GetFirstObjectInstance);
Monitor.Pulse(Global.GetSecondObjectInstance);
///
}
}
It seems like this is an invalid operation, because at the stage where the Monitor.Pulse is called from the InsertNewAuction method I get an exception. Something like "Object synchronization method was called from an unsynchronized block of code." Is there any way of doing this? Thanks for your help
As to the specific error you're seeing, this is because Monitor.Pulse must be called inside the Monitor lock, like this (I've used lock rather than Enter/Exit, as it's safer for making sure the lock is always released, since it uses a proper try/finally block):
lock (Global.GetFirstObjectInstance)
{
Monitor.Pulse(Global.GetFirstObjectInstance);
}
In regard to the more general design question here, it's often dangerous to expose lock objects as public (or even worse, global) fields. In particular, it can be a recipe for deadlocks when multiple global locks are exposed and acquired in differing orders or when you have cases like blocking dispatches to the UI thread while holding a lock. Consider looking into alternate ways to accomplish what you're after.
As noted in the other answer, you have to acquire the lock before you can call Monitor.Pulse() on the monitor object.
That said, your code has at least one other serious bug: you are not initializing the synchronization object in a thread-safe way, which could easily lead to two different threads using two different object instances, resulting in no synchronization between those threads:
public static object GetFirstObjectInstance
{
get
{
if(o1==null)
{
o1=new object();
}
return o1;
}
}
If two threads call this getter simultaneously, they each may see o1 as null and try to initialize it. Then each might return a different value for the object instance.
You should simply initialize the object in a initializer:
private static readonly object o1 = new object();
And then return it from the getter:
public static object GetFirstObjectInstance { get { return o1; } }
That addresses the thread-safety issue. But you still have other issues with the code. First, you should encapsulate synchronization in an object, not expose the actual synchronization object instance. Second, assuming you are going to expose the synchronization object, I don't understand why you bother with the property, since you made the field public. The field should be private if you want to use a property as well.
It would also be better if the property followed normal .NET naming conventions. A method that returned the object would have "Get" in the name, but a property would not. Just name it "FirstObjectInstance".
Also as noted by Dan, use lock everywhere you want to acquire the lock.
There may be other issues in the code as well...I didn't do a thorough review. But the above you need to fix for sure.
Why is it a bad practice to use lock as in the following code, I'm assuming this is a bad practice based on the answers in this SO question here
private void DoSomethingUseLess()
{
List<IProduct> otherProductList = new List<IProduct>();
Parallel.ForEach(myOriginalProductList, product =>
{
//Some code here removed for brevity
//Some more code here :)
lock (otherProductList)
{
otherProductList.Add((IProduct)product.Clone());
}
});
}
The answers over there mentions that it is bad practice , but they don't say why
Note: Please ignore the usefulness of the code, this is just for example purpose and i know it is not at all useful
From the C# language reference here:
In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:
lock (this) is a problem if the instance can be accessed publicly.
lock (typeof (MyType)) is a problem if MyType is publicly accessible.
lock("myLock") is a problem because any other code in the process
using the same string, will share the same lock.
Best practice is to define a private object to lock on, or a private
static object variable to protect data common to all instances.
In your case, I would read the above guidance as suggesting that locking on the collection you will be modifying is bad practise. For example, if you wrote this code:
lock (otherProductList)
{
otherProductList = new List<IProduct>();
}
...then your lock will be worthless. For these reasons it's recommended to use a dedicated object variable for locking.
Note that this doesn't mean your application will break if you use the code you posted. "Best practices" are usually defined to provide easily-repeated patterns that are more technically resilient. That is, if you follow best practice and have a dedicated "lock object," you are highly unlikely to ever write broken lock-based code; if you don't follow best practice then, maybe one time in a hundred, you'll get bitten by an easily-avoided problem.
Additionally (and more generally), code written using best practices is typically more easily modified, because you can be less wary of unexpected side-effects.
It might be not a good idea indeed, because if someone else uses the same object reference to do a lock, you could have a deadlock. If there is a chance your locked object is accessible outside your own code, then someone else could break your code.
Imagine the following example based on your code:
namespace ClassLibrary1
{
public class Foo : IProduct
{
}
public interface IProduct
{
}
public class MyClass
{
public List<IProduct> myOriginalProductList = new List<IProduct> { new Foo(), new Foo() };
public void Test(Action<IEnumerable<IProduct>> handler)
{
List<IProduct> otherProductList = new List<IProduct> { new Foo(), new Foo() };
Parallel.ForEach(myOriginalProductList, product =>
{
lock (otherProductList)
{
if (handler != null)
{
handler(otherProductList);
}
otherProductList.Add(product);
}
});
}
}
}
Now you compile your library, send it to a customer, and this customer writes in his code:
public class Program
{
private static void Main(string[] args)
{
new MyClass().Test(z => SomeMethod(z));
}
private static void SomeMethod(IEnumerable<IProduct> myReference)
{
Parallel.ForEach(myReference, item =>
{
lock (myReference)
{
// Some stuff here
}
});
}
}
Then there could be a nice hard-to-debug deadlock for your customer, each of two used thread waiting for the otherProductList instance to be not locked anymore.
I agree, this scenario is unlikely to happen, but it illustrates that if your locked reference is visible in a piece of code you do not own, by any possible way, then there's a possibility for the final code to be broken.
My question may sound like many others here but it has a flavor I didn't find.
I am trying to understand the following logic
A generic object
public class GenericClass
{
public static void DoSomething(Object lockObj)
{
lock(lockObj)
{
// do something here
}
}
}
Class A
internal class A
{
private static _aLock = new Object();
public void Do_A_Thing()
{
GenericClass.DoSomething(_aLock);
}
}
Class B
internal class B
{
private static _bLock = new Object();
public void Do_B_Thing()
{
GenericClass.DoSomething(_bLock);
}
}
I just hope to confirm if my explanation is correct:
If multiple threads of class "A" will attempt simultaneously access code in "genericClass" method "DoSomething", this method will be locked to all but one instance of class "A". But a single instance of class "B" will be able to proceed with execution any time. If class "B" will also have multiple instances execute, they will not interfere with class "A" locks.
Is this correct based on what you see above?
Yes, your description sounds correct. It is perhaps a little unusual to pass the lock object in, but it'll work fine. The only change I would suggest is to make the static fields readonly so you can't accidentally change the value to a different object reference.
Your conclusion is correct but it is not a good practice to pass locked object around. I suggest to put the lock inside class A and B respectively.
I suggest to write:
internal class A
{
private static readonly _aLock = new Object();
public void Do_A_Thing()
{
lock (_aLock)
{
GenericClass.DoSomething();
}
}
}
Do you have a specific reason to put the lock in another class? Maybe you can solve your problem in a different way?
Also keep in mind that in some conditions, maybe it is not your case, you can have a deadlock if class A and B call each other (A->B->A).
Yes, that is correct. The locks in A and the locks in B are completely unaware of each other. The code will only be blocked when there is another thread locking it with the same object as identifier.
If you are using generics, then something like
public class MyGadget<T>
{
static readonly SyncRoot = new object() ;
public T SynchronizedMethod()
{
lock ( SyncRoot )
{
SynchronizedMethodGuts() ;
}
}
}
should do what you want because MyGadget<Foo> and MyGadget<Bar> are different classes: they each have their own, different SyncRoot field.
Is the snippet below "safe" for performing some initialization once in a multithreaded program?
I'm a bit worried that boxing/unboxing might cause some problem...
private static object initialized = false;
public static void Initialize()
{
lock (initialized)
{
if ((bool)initialized == false)
{
DoInitialization();
initialized = true;
}
}
}
Note that I can't just do the initialization from Main or some other single threaded context.
You are right - that's not going to work because you are reassigning the object you are locking on.
You can do this with two seperate members - an object to lock on that is assigned only once, and then a boolean that you can read or assign to (after you have locked).
You may also want to consider if a singleton would be appropriate here.
Try a double-checked locking.
private static volatile bool initialized = false;
private static object syncObject = new object();
public static void Initialize() {
if (!initialized) {
lock (syncObject) {
if (!initialized) {
DoInitialization();
initialized = true;
}
}
}
}
A few options:
lock on a once-assigned reference-type, as Mark has mentioned.
Initialize on the static-constructor, which is guaranteed to only run once. Con: Hard to control when you want the initialization to occur.
If possible, the Lazy class, which is thread-safe.
All 3 methods can also be used to create Singletons.
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) {}
}