Thread-safe use of a singleton's members - c#

I have a C# singleton class that multiple classes use. Is access through Instance to the Toggle() method thread-safe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
public class MyClass
{
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private int value = 0;
public int Toggle()
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}

Is access through 'Instance' to the 'Toggle()' class threadsafe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
No, it's not threadsafe.
Basically, both threads can run the Toggle function at the same time, so this could happen
// thread 1 is running this code
if(value == 0)
{
value = 1;
// RIGHT NOW, thread 2 steps in.
// It sees value as 1, so runs the other branch, and changes it to 0
// This causes your method to return 0 even though you actually want 1
}
else if(value == 1)
{
value = 0;
}
return value;
You need to operate with the following assumption.
If 2 threads are running, they can and will interleave and interact with eachother randomly at any point. You can be half way through writing or reading a 64 bit integer or float (on a 32 bit CPU) and another thread can jump in and change it out from underneath you.
If the 2 threads never access anything in common, it doesn't matter, but as soon as they do, you need to prevent them from stepping on each others toes. The way to do this in .NET is with locks.
You can decide what and where to lock by thinking about things like this:
For a given block of code, if the value of something got changed out from underneath me, would it matter? If it would, you need to lock that something for the duration of the code where it would matter.
Looking at your example again
// we read value here
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
// and we return it here
return value;
In order for this to return what we expect it to, we assume that value won't get changed between the read and the return. In order for this assumption to actually be correct, you need to lock value for the duration of that code block.
So you'd do this:
lock( value )
{
if(value == 0)
... // all your code here
return value;
}
HOWEVER
In .NET you can only lock Reference Types. Int32 is a Value Type, so we can't lock it.
We solve this by introducing a 'dummy' object, and locking that wherever we'd want to lock 'value'.
This is what Ben Scheirman is referring to.

The original impplementation is not thread safe, as Ben points out
A simple way to make it thread safe is to introduce a lock statement. Eg. like this:
public class MyClass
{
private Object thisLock = new Object();
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private Int32 value = 0;
public Int32 Toggle()
{
lock(thisLock)
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}
}

I'd also add a protected constructor to MyClass to prevent the compiler from generating a public default constructor.

That is what I thought. But, I I'm
looking for the details... 'Toggle()'
is not a static method, but it is a
member of a static property (when
using 'Instance'). Is that what makes
it shared among threads?
If your application is multi-threaded and you can forsee that multiple thread will access that method, that makes it shared among threads. Because your class is a Singleton you know that the diferent thread will access the SAME object, so be cautioned about the thread-safety of your methods.
And how does this apply to singletons
in general. Would I have to address
this in every method on my class?
As I said above, because its a singleton you know diferent thread will acess the same object, possibly at the same time. This does not mean you have to make every method obtain a lock. If you notice that a simultaneos invocation can lead to corrupted state of the class, then you should apply the method mentioned by #Thomas

Can I assume that the singleton pattern exposes my otherwise lovely thread-safe class to all the thread problems of regular static members?
No. Your class is simply not threadsafe. The singleton has nothing to do with it.
(I'm getting my head around the fact that instance members called on a static object cause threading problems)
It's nothing to do with that either.
You have to think like this: Is it possible in my program for 2 (or more) threads to access this piece of data at the same time?
The fact that you obtain the data via a singleton, or static variable, or passing in an object as a method parameter doesn't matter. At the end of the day it's all just some bits and bytes in your PC's RAM, and all that matters is whether multiple threads can see the same bits.

Your thread could stop in the middle of that method and transfer control to a different thread. You need a critical section around that code...
private static object _lockDummy = new object();
...
lock(_lockDummy)
{
//do stuff
}

I was thinking that if I dump the singleton pattern and force everyone to get a new instance of the class it would ease some problems... but that doesn't stop anyone else from initializing a static object of that type and passing that around... or from spinning off multiple threads, all accessing 'Toggle()' from the same instance.
Bingo :-)
I get it now. It's a tough world. I wish I weren't refactoring legacy code :(
Unfortunately, multithreading is hard and you have to be very paranoid about things :-)
The simplest solution in this case is to stick with the singleton, and add a lock around the value, like in the examples.

Quote:
if(value == 0) { value = 1; }
if(value == 1) { value = 0; }
return value;
value will always be 0...

Well, I actually don't know C# that well... but I am ok at Java, so I will give the answer for that, and hopefully the two are similar enough that it will be useful. If not, I apologize.
The answer is, no, it's not safe. One thread could call Toggle() at the same time as the other, and it is possible, although unlikely with this code, that Thread1 could set value in between the times that Thread2 checks it and when it sets it.
To fix, simply make Toggle() synchronized. It doesn't block on anything or call anything that might spawn another thread which could call Toggle(), so that's all you have to do save it.

Related

Thread Safe Properties in C#

I am trying to create thread safe properties in C# and I want to make sure that I am on the correct path - here is what I have done -
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
_AvgBuyPrice = value;
}
}
}
Reading this posting, it would seem as if this isn't the correct way of doing it -
C# thread safety with get/set
however, this article seems to suggest otherwise,
http://www.codeproject.com/KB/cs/Synchronized.aspx
Does anybody have a more definitive answer?
Edit:
The reason that I want to do the Getter/Setter for this property is b/c I actually want it to fire an event when it is set - so the code would actually be like this -
public class PLTracker
{
public PLEvents Events;
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
Events.AvgBuyPriceUpdate(value);
_AvgBuyPrice = value;
}
}
}
}
public class PLEvents
{
public delegate void PLUpdateHandler(double Update);
public event PLUpdateHandler AvgBuyPriceUpdateListener;
public void AvgBuyPriceUpdate(double AvgBuyPrice)
{
lock (this)
{
try
{
if (AvgBuyPriceUpdateListener!= null)
{
AvgBuyPriceUpdateListener(AvgBuyPrice);
}
else
{
throw new Exception("AvgBuyPriceUpdateListener is null");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
I am pretty new to making my code thread safe so please feel free to tell me if I am going about it in the totally wrong way!
Will
The locks, as you have written them are pointless. The thread reading the variable, for example, will:
Acquire the lock.
Read the value.
Release the lock.
Use the read value somehow.
There is nothing to stop another thread from modifying the value after step 3. As variable access in .NET is atomic (see caveat below), the lock is not actually achieving much here: merely adding an overhead. Contrast with the unlocked example:
Read the value.
Use the read value somehow.
Another thread may alter the value between step 1 and 2 and this is no different to the locked example.
If you want to ensure state does not change when you are doing some processing, you must read the value and do the processing using that value within the contex of the lock:
Acquire the lock.
Read the value.
Use the read value somehow.
Release the lock.
Having said that, there are cases when you need to lock when accessing a variable. These are usually due to reasons with the underlying processor: a double variable cannot be read or written as a single instruction on a 32 bit machine, for example, so you must lock (or use an alternative strategy) to ensure a corrupt value is not read.
Since you have a primitive value this locking will work fine - the issue in the other question was that the property value was a more complex class (a mutable reference type) - the locking will protect accessing and retrieving the instance of the double value held by your class.
If your property value is a mutable reference type on the other hand locking will not protect from changing the class instance once retrieved using its methods, which is what the other poster wanted it to do.
Thread safety is not something you should add to your variables, it is something you should add to your "logic". If you add locks to all your variables, your code will still not necessarily be thread safe, but it will be slow as hell.
To write a thread-safe program, Look at your code and decide where multiple threads could be using the same data/objects. Add locks or other safety measures to all those critical places.
For instance, assuming the following bit of pseudo code:
void updateAvgBuyPrice()
{
float oldPrice = AvgBuyPrice;
float newPrice = oldPrice + <Some other logic here>
//Some more new price calculation here
AvgBuyPrice = newPrice;
}
If this code is called from multiple threads at the same time, your locking logic has no use. Imagine thread A getting AvgBuyPrice and doing some calculations. Now before it is done, thread B is also getting the AvgBuyPrice and starting calculations. Thread A in the meantime is done and will assign the new value to AvgBuyPrice. However, just moments later, it will be overwritten by thread B (which still used the old value) and the work of thread A has been lost completely.
So how do you fix this? If we were to use locks (which would be the ugliest and slowest solution, but the easiest if you're just starting with multithreading), we need to put all the logic which changes AvgBuyPrice in locks:
void updateAvgBuyPrice()
{
lock(AvgBuyPriceLocker)
{
float oldPrice = AvgBuyPrice;
float newPrice = oldPrice + <Some other code here>
//Some more new price calculation here
AvgBuyPrice = newPrice;
}
}
Now, if thread B wants to do the calculations while thread A is still busy, it will wait until thread A is done and then do its work using the new value. Keep in mind though, that any other code that also modifies AvgBuyPrice should also lock AvgBuyPriceLocker while it's working!
Still, this will be slow if used often. Locks are expensive and there are a lot of other mechanism to avoid locks, just search for lock-free algorithms.
Reading and writing of doubles is atomic anyway (source) reading and writing of doubles isn't atomic and so it would be necessary to protect access to a double using a lock, however for many types reading and writing is atomic and so the following would be just as safe:
private float AvgBuyPrice
{
get;
set;
}
My point is that thread safety is more complex than simply protecting each of your properties. To give a simple example suppose I have two properties AvgBuyPrice and StringAvgBuyPrice:
private string StringAvgBuyPrice { get; set; }
private float AvgBuyPrice { get; set; }
And suppose I update the average buy price thusly:
this.AvgBuyPrice = value;
this.StringAvgBuyPrice = value.ToString();
This clearly isn't thread safe and individually protecting properties in the above way won't help at all. In this case the locking should be performed at a different level rather than at a per-property level.
Although an old question, it gets on top of Google searches, so I add a reply. In you example, the get locker will not be released after return. Therefore, I suggest to use the ReaderWriterLockSlim within a try-finally block in such a case, which is very well suitable for the result you try to accomplish. It allows multiple threads for reading or exclusive access for writing:
private readonly ReaderWriterLockSlim AvgBuyPriceLocker = new ReaderWriterLockSlim();
private double _AvgBuyPrice = 0;
public double AvgBuyPrice {
get {
AvgBuyPriceLocker.EnterReadLock();
try { return _AvgBuyPrice; }
finally { AvgBuyPriceLocker.ExitReadLock(); }
}
set {
AvgBuyPriceLocker.EnterWriteLock();
try { _AvgBuyPrice = value; }
finally { AvgBuyPriceLocker.ExitWriteLock(); }
}
}

Boolean Property Getter and Setter Locking

Is there any reason why you would create locks around the getter and setter of a boolean property like this?
private _lockObject = new object();
private bool _myFlag;
public bool MyFlag
{
get
{
lock (_lockObject)
{
return _myFlag;
}
}
set
{
lock (_lockObject)
{
_myFlag = value;
}
}
}
Well, you don't need locks necessarily - but if you want one thread to definitely read the value that another thread has written, you either need locks or a volatile variable.
I've personally given up trying to understand the precise meaning of volatile. I try to avoid writing my own lock-free code, instead relying on experts who really understand the memory model.
EDIT: As an example of the kind of problem this can cause, consider this code:
using System;
using System.Threading;
public class Test
{
private static bool stop = false;
private bool Stop
{
get { return stop; }
set { stop = value; }
}
private static void Main()
{
Thread t = new Thread(DoWork);
t.Start();
Thread.Sleep(1000); // Let it get started
Console.WriteLine("Setting stop flag");
Stop = true;
Console.WriteLine("Set");
t.Join();
}
private static void DoWork()
{
Console.WriteLine("Tight looping...");
while (!Stop)
{
}
Console.WriteLine("Done.");
}
}
That program may or may not terminate. I've seen both happen. There's no guarantee that the "reading" thread will actually read from main memory - it can put the initial value of stop into a register and just keep using that forever. I've seen that happen, in reality. It doesn't happen on my current machines, but it may do on my next.
Putting locks within the property getter/setter as per the code in the question would make this code correct and its behaviour predictable.
For more on this, see this blog post by Eric Lippert.
Reads and writes of bool are atomic.
However the name "flag" indicates that separate threads will be reading/writing until some condition occurred. To avoid unexpected behavior due to optimization you should consider adding the volatile keyword to you bool declaration.
There's no reason to have a lock right there.
Taking a lock may well be appropriate in your design, but it's very doubtful that this is the right granularity.
You need to make your design thread-safe, not individual properties (or even entire objects).

Is the following C# code thread safe?

I am trying to learn the threading in C#. Today I sow the following code at http://www.albahari.com/threading/:
class ThreadTest
{
bool done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (!done) { done = true; Console.WriteLine ("Done"); }
}
}
In Java unless you define the "done" as volatile the code will not be safe. How does C# memory model handles this?
Guys, Thanks all for the answers. Much appreciated.
Well, there's the clear race condition that they could both see done as false and execute the if body - that's true regardless of memory model. Making done volatile won't fix that, and it wouldn't fix it in Java either.
But yes, it's feasible that the change made in one thread could happen but not be visible until in the other thread. It depends on CPU architecture etc. As an example of what I mean, consider this program:
using System;
using System.Threading;
class Test
{
private bool stop = false;
static void Main()
{
new Test().Start();
}
void Start()
{
new Thread(ThreadJob).Start();
Thread.Sleep(500);
stop = true;
}
void ThreadJob()
{
int x = 0;
while (!stop)
{
x++;
}
Console.WriteLine("Counted to {0}", x);
}
}
While on my current laptop this does terminate, I've used other machines where pretty much the exact same code would run forever - it would never "see" the change to stop in the second thread.
Basically, I try to avoid writing lock-free code unless it's using higher-level abstractions provided by people who really know their stuff - like the Parallel Extensions in .NET 4.
There is a way to make this code lock-free and correct easily though, using Interlocked. For example:
class ThreadTest
{
int done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (Interlocked.CompareExchange(ref done, 1, 0) == 0)
{
Console.WriteLine("Done");
}
}
}
Here the change of value and the testing of it are performed as a single unit: CompareExchange will only set the value to 1 if it's currently 0, and will return the old value. So only a single thread will ever see a return value of 0.
Another thing to bear in mind: your question is fairly ambiguous, as you haven't defined what you mean by "thread safe". I've guessed at your intention, but you never made it clear. Read this blog post by Eric Lippert - it's well worth it.
No, it's not thread safe. You could potentially have one thread check the condition (if(!done)), the other thread check that same condition, and then the first thread executes the first line in the code block (done = true).
You can make it thread safe with a lock:
lock(this)
{
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
Even in Java with volatile, both threads could enter the block with the WriteLine.
If you want mutual exclusion you need to use a real synchronisation object such as a lock.
onle way this is thread safe is when you use atomic compare and set in the if test
if(atomicBool.compareAndSet(false,true)){
Console.WriteLine("Done");
}
You should do something like this:
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
}
The reason you want to use an generic object, rather than "this", is that if your object (aka "this") changes at all it is considered another object. Thus your lock does not work any more.
Another small thing you might consider is this. It is a "good practices" thing, so nothing severe.
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
}
}
//This line of code does not belong inside the lock.
Console.WriteLine("Done");
}
Never have code inside a lock that does not need to be inside a lock. This is due to the delay this causes. If you have lots of threads you can gain a lot of performance from removing all this unnecessary waiting.
Hope it helps :)

C# thread safety with get/set

This is a detail question for C#.
Suppose I've got a class with an object, and that object is protected by a lock:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
I want a polling thread to be able to query that property. I also want the thread to update properties of that object occasionally, and sometimes the user can update that property, and the user wants to be able to see that property.
Will the following code properly lock the data?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
By 'properly', what I mean is, if I want to call
MyProperty.Field1 = 2;
or whatever, will the field be locked while I do the update? Is the setting that's done by the equals operator inside the scope of the 'get' function, or will the 'get' function (and hence the lock) finish first, and then the setting, and then 'set' gets called, thus bypassing the lock?
Edit: Since this apparently won't do the trick, what will? Do I need to do something like:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
which more or less just makes sure that I only have access to a copy, meaning that if I were to have two threads call a 'get' at the same time, they would each start with the same value of Field1 (right?). Is there a way to do read and write locking on a property that makes sense? Or should I just constrain myself to locking on sections of functions rather than the data itself?
Just so that this example makes sense: MyObject is a device driver that returns status asynchronously. I send it commands via a serial port, and then the device responds to those commands in its own sweet time. Right now, I have a thread that polls it for its status ("Are you still there? Can you accept commands?"), a thread that waits for responses on the serial port ("Just got status string 2, everything's all good"), and then the UI thread which takes in other commands ("User wants you to do this thing.") and posts the responses from the driver ("I've just done the thing, now update the UI with that"). That's why I want to lock on the object itself, rather than the fields of the object; that would be a huge number of locks, a, and b, not every device of this class has the same behavior, just general behavior, so I'd have to code lots of individual dialogs if I individualized the locks.
No, your code won't lock access to the members of the object returned from MyProperty. It only locks MyProperty itself.
Your example usage is really two operations rolled into one, roughly equivalent to this:
// object is locked and then immediately released in the MyProperty getter
MyObject o = MyProperty;
// this assignment isn't covered by a lock
o.Field1 = 2;
// the MyProperty setter is never even called in this example
In a nutshell - if two threads access MyProperty simultaneously, the getter will briefly block the second thread until it returns the object to the first thread, but it'll then return the object to the second thread as well. Both threads will then have full, unlocked access to the object.
EDIT in response to further details in the question
I'm still not 100% certain what you're trying to achieve, but if you just want atomic access to the object then couldn't you have the calling code lock against the object itself?
// quick and dirty example
// there's almost certainly a better/cleaner way to do this
lock (MyProperty)
{
// other threads can't lock the object while you're in here
MyProperty.Field1 = 2;
// do more stuff if you like, the object is all yours
}
// now the object is up-for-grabs again
Not ideal, but so long as all access to the object is contained in lock (MyProperty) sections then this approach will be thread-safe.
Concurrent programming would be pretty easy if your approach could work. But it doesn't, the iceberg that sinks that Titanic is, for example, the client of your class doing this:
objectRef.MyProperty += 1;
The read-modify-write race is pretty obvious, there are worse ones. There is absolutely nothing you can do to make your property thread-safe, other than making it immutable. It is your client that needs to deal with the headache. Being forced to delegate that kind of responsibility to a programmer that is least likely to get it right is the Achilles-heel of concurrent programming.
As others have pointed out, once you return the object from the getter, you lose control over who accesses the object and when. To do what you're wanting to do, you'll need to put a lock inside the object itself.
Perhaps I don't understand the full picture, but based on your description, it doesn't sound like you'd necessarily need to have a lock for each individual field. If you have a set of fields are simply read and written via the getters and setters, you could probably get away with a single lock for these fields. There is obviously potential that you'll unnecessarily serialize the operation of your threads this way. But again, based on your description, it doesn't sound like you're aggressively accessing the object either.
I would also suggest using an event instead of using a thread to poll the device status. With the polling mechanism, you're going to be hitting the lock each time the thread queries the device. With the event mechanism, once the status changes, the object would notify any listeners. At that point, your 'polling' thread (which would no longer be polling) would wake up and get the new status. This will be much more efficient.
As an example...
public class Status
{
private int _code;
private DateTime _lastUpdate;
private object _sync = new object(); // single lock for both fields
public int Code
{
get { lock (_sync) { return _code; } }
set
{
lock (_sync) {
_code = value;
}
// Notify listeners
EventHandler handler = Changed;
if (handler != null) {
handler(this, null);
}
}
}
public DateTime LastUpdate
{
get { lock (_sync) { return _lastUpdate; } }
set { lock (_sync) { _lastUpdate = value; } }
}
public event EventHandler Changed;
}
Your 'polling' thread would look something like this.
Status status = new Status();
ManualResetEvent changedEvent = new ManualResetEvent(false);
Thread thread = new Thread(
delegate() {
status.Changed += delegate { changedEvent.Set(); };
while (true) {
changedEvent.WaitOne(Timeout.Infinite);
int code = status.Code;
DateTime lastUpdate = status.LastUpdate;
changedEvent.Reset();
}
}
);
thread.Start();
The lock scope in your example is in the incorrect place - it needs to be at the scope of the 'MyObject' class's property rather than it's container.
If the MyObject my object class is simply used to contain data that one thread wants to write to, and another (the UI thread) to read from then you might not need a setter at all and construct it once.
Also consider if placing locks at the property level is the write level of lock granularity; if more than one property might be written to in order to represent the state of a transaction (eg: total orders and total weight) then it might be better to have the lock at the MyObject level (i.e. lock( myObject.SyncRoot ) ... )
In the code example you posted, a get is never preformed.
In a more complicated example:
MyProperty.Field1 = MyProperty.doSomething() + 2;
And of course assuming you did a:
lock (mLock)
{
// stuff...
}
In doSomething() then all of the lock calls would not be sufficient to guarantee synchronization over the entire object. As soon as the doSomething() function returns, the lock is lost, then the addition is done, and then the assignment happens, which locks again.
Or, to write it another way you can pretend like the locks are not done amutomatically, and rewrite this more like "machine code" with one operation per line, and it becomes obvious:
lock (mLock)
{
val = doSomething()
}
val = val + 2
lock (mLock)
{
MyProperty.Field1 = val
}
The beauty of multithreading is that you don't know which order things will happen in. If you set something on one thread, it might happen first, it might happen after the get.
The code you've posted with lock the member while it's being read and written. If you want to handle the case where the value is updated, perhaps you should look into other forms of synchronisation, such as events. (Check out the auto/manual versions). Then you can tell your "polling" thread that the value has changed and it's ready to be reread.
In your edited version, you are still not providing a threadsafe way to update MyObject. Any changes to the object's properties will need to be done inside a synchronized/locked block.
You can write individual setters to handle this, but you've indicated that this will be difficult because of the large number fields. If indeed the case (and you haven't provided enough information yet to assess this), one alternative is to write a setter that uses reflection; this would allow you to pass in a string representing the field name, and you could dynamically look up the field name and update the value. This would allow you to have a single setter that would work on any number of fields. This isn't as easy or as efficient but it would allow you to deal with a large number of classes and fields.
You have implemented a lock for getting/setting the object but you have not made the object thread safe, which is another story.
I have written an article on immutable model classes in C# that might be interesting in this context: http://rickyhelgesson.wordpress.com/2012/07/17/mutable-or-immutable-in-a-parallel-world/
Does C# locks not suffer from the same locking issues as other languages then?
E.G.
var someObj = -1;
// Thread 1
if (someObj = -1)
lock(someObj)
someObj = 42;
// Thread 2
if (someObj = -1)
lock(someObj)
someObj = 24;
This could have the problem of both threads eventually getting their locks and changing the value. This could lead to some strange bugs. However you don't want to unnecessarily lock the object unless you need to. In this case you should consider the double checked locking.
// Threads 1 & 2
if (someObj = -1)
lock(someObj)
if(someObj = -1)
someObj = {newValue};
Just something to keep in mind.

Instance constructor sets a static member, is it thread safe?

I am re-factoring some code and am wondering about the use of a lock in the instance constructor.
public class MyClass {
private static Int32 counter = 0;
private Int32 myCount;
public MyClass() {
lock(this) {
counter++;
myCount = counter;
}
}
}
Please confirm
Instance constructors are thread-safe.
The lock statement prevents access to that code block, not to the static 'counter' member.
If the intent of the original programmer were to have each instance know its 'count', how would I synchronize access to the 'counter' member to ensure that another thread isn't new'ing a MyClass and changing the count before this one sets its count?
FYI - This class is not a singleton. Instances must simply be aware of their number.
If you are only incrementing a number, there is a special class (Interlocked) for just that...
http://msdn.microsoft.com/en-us/library/system.threading.interlocked.increment.aspx
Interlocked.Increment Method
Increments a specified variable and stores the result, as an atomic operation.
System.Threading.Interlocked.Increment(myField);
More information about threading best practices...
http://msdn.microsoft.com/en-us/library/1c9txz50.aspx
I'm guessing this is for a singleton pattern or something like it. What you want to do is not lock your object, but lock the counter while your are modifying it.
private static int counter = 0;
private static object counterLock = new Object();
lock(counterLock) {
counter++;
myCounter = counter;
}
Because your current code is sort of redundant. Especially being in the constructor where there is only one thread that can call a constructor, unlike with methods where it could be shared across threads and be accessed from any thread that is shared.
From the little I can tell from you code, you are trying to give the object the current count at the time of it being created. So with the above code the counter will be locked while the counter is updated and set locally. So all other constructors will have to wait for the counter to be released.
#ajmastrean
I am not saying you should use the singleton pattern itself, but adopt its method of encapsulating the instantiation process.
i.e.
Make the constructor private.
Create a static instance method that returns the type.
In the static instance method, use the lock keyword before instantiating.
Instantiate a new instance of the type.
Increment the count.
Unlock and return the new instance.
EDIT
One problem that has occurred to me, if how would you know when the count has gone down? ;)
EDIT AGAIN
Thinking about it, you could add code to the destructor that calls another static method to decrement the counter :D
You can use another static object to lock on it.
private static Object lockObj = new Object();
and lock this object in the constructor.
lock(lockObj){}
However, I'm not sure if there are situations that should be handled because of compiler optimization in .NET like in the case of java
The most efficient way to do this would be to use the Interlocked increment operation. It will increment the counter and return the newly set value of the static counter all at once (atomically)
class MyClass {
static int _LastInstanceId = 0;
private readonly int instanceId;
public MyClass() {
this.instanceId = Interlocked.Increment(ref _LastInstanceId);
}
}
In your original example, the lock(this) statement will not have the desired effect because each individual instance will have a different "this" reference, and multiple instances could thus be updating the static member at the same time.
In a sense, constructors can be considered to be thread safe because the reference to the object being constructed is not visible until the constructor has completed, but this doesn't do any good for protecting a static variable.
(Mike Schall had the interlocked bit first)
I think if you modify the Singleton Pattern to include a count (obviously using the thread-safe method), you will be fine :)
Edit
Crap I accidentally deleted!
I am not sure if instance constructors ARE thread safe, I remember reading about this in a design patterns book, you need to ensure that locks are in place during the instantiation process, purely because of this..
#Rob
FYI, This class may not be a singleton, I need access to different instances. They must simply maintain a count. What part of the singleton pattern would you change to perform 'counter' incrementing?
Or are you suggesting that I expose a static method for construction blocking access to the code that increments and reads the counter with a lock.
public MyClass {
private static Int32 counter = 0;
public static MyClass GetAnInstance() {
lock(MyClass) {
counter++;
return new MyClass();
}
}
private Int32 myCount;
private MyClass() {
myCount = counter;
}
}

Categories