Thread-safe initialization of static variables - c#

I've been using this pattern to initialize static data in my classes. It looks thread safe to me, but I know how subtle threading problems can be. Here's the code:
public class MyClass // bad code, do not use
{
static string _myResource = "";
static volatile bool _init = false;
public MyClass()
{
if (_init == true) return;
lock (_myResource)
{
if (_init == true) return;
Thread.Sleep(3000); // some operation that takes a long time
_myResource = "Hello World";
_init = true;
}
}
public string MyResource { get { return _myResource; } }
}
Are there any holes here? Maybe there is a simpler way to do this.
UPDATE: Consensus seems to be that a static constructor is the way to go. I came up with the following version using a static constructor.
public class MyClass
{
static MyClass() // a static constructor
{
Thread.Sleep(3000); // some operation that takes a long time
_myResource = "Hello World";
}
static string _myResource = null;
public MyClass() { LocalString = "Act locally"; } // an instance constructor
// use but don't modify
public bool MyResourceReady { get { return _myResource != null; } }
public string LocalString { get; set; }
}
I hope this is better.

You can use static constructors to intialize your static variables, which C# guarantees will only be called once within each AppDomain. Not sure if you considered them.
So you can read this: http://msdn.microsoft.com/en-us/library/aa645612(VS.71).aspx (Static Constructors)
And this: Is the C# static constructor thread safe?

Performing a lock() on _myResource and changing it inside lock() statement seems like a bad idea.
Consider following workflow:
thread 1 calls MyClass().
execution stops before line _init = true; right after assigning _myResource.
processor switches to thread 2.
thread 2 calls MyClass(). Since _init is still false and refrence _myResource changed, it succesfully enters lock() statement block.
_init is still false, so thread 2 reassigns _myResource.
Workaround: create a static object and lock on this object instead of initialized resource:
private static readonly object _resourceLock = new object();
/*...*/
lock(_resourceLock)
{
/*...*/
}

Your class is not safe:
You change the object you're locking on after you've locked on it.
You have a property that gets the resource without locking it.
You lock on a primitive type, which is generally not a good practice.
This should do it for you:
public class MyClass
{
static readonly object _sync = new object();
static string _myResource = "";
static volatile bool _init = false;
public MyClass()
{
if (_init == true) return;
lock (_sync)
{
if (_init == true) return;
Thread.Sleep(3000); // some operation that takes a long time
_myResource = "Hello World";
_init = true;
}
}
public string MyResource
{
get
{
MyClass ret; // Correct
lock(_sync)
{
ret = _myResource;
}
return ret;
}
}
}
Update:
Correct, the static resource should not be returned directly... I've corrected my example accordingly.

Depending on your use case (i.e. if threads don't need to pass information to each other using this variable), marking the member variable as [ThreadStatic] may be a solution.
See here.

static string _myResource = "";
...
public MyClass()
{
...
lock (_myResource)
{
}
}
Due to string interning, you should not lock on a string literal. If you lock on a string literal and that string literal is used by multiple classes then you may be sharing that lock. This can potentially cause unexpected behavior.

Related

Should an object reference passed to a Thread be marked as volatile? Are delegates affected?

I have a simple test case that I borrowed from another question on here but modified with slightly different but simple contrived examples. Given:
class Foo
{
public bool Complete; // { get; set; }
public bool IsComplete()
{
return Complete ;
}
}
class Program
{
static Foo foo = new Foo();
static void ThreadProc()
{
bool toggle = false;
// while (!foo.Complete) toggle = !toggle;
while (!foo.IsComplete()) toggle = !toggle;
Console.WriteLine("Thread done");
}
static void Main()
{
var t = new Thread(ThreadProc);
t.Start();
Thread.Sleep(1000);
foo.Complete = true;
t.Join();
}
Given that ThreadProc is calling IsComplete() the compiler doesn't seem to cache the Complete variable. But however I can't find a guarantee that the compiler doesn't generate cache optimisations for method calls on an object passed from a different thread.
But I'm worried about this scenario:
If ThreadProc is running on a different processor to main thread
can it deep copy the entire code of object foo into its thread cache?
Meaning I will be updating an entirely different object instance.
If so would making the reference volatile necessary?
I don't understand what's happening here. But it seems to prove my worry above, it never exits (but exits in Debug mode):
class Foo
{
public bool Complete; // { get; set; }
public bool IsComplete()
{
return Complete ;
}
}
class Program
{
static void ThreadProc(Foo foo)
{
bool toggle = false;
// while (!foo.Complete) toggle = !toggle;
while (!foo.IsComplete()) toggle = !toggle;
Console.WriteLine("Thread done");
}
static void Main()
{
Foo foo = new Foo();
var t = new Thread(()=>ThreadProc(foo));
t.Start();
Thread.Sleep(1000);
foo.Complete = true;
t.Join();
Console.ReadLine();
}
}
Yet, the below completes! Pretty much the same thing written differently.
I can't see how the anonymous lambda is changing things. It should still point to the same object instance:
public class Foo
{
public bool Complete; // { get; set; }
private FooThread fooThread;
public Foo()
{
fooThread = new FooThread(this);
}
public bool IsComplete()
{
return Complete ;
}
public void StartThread()
{
var t = new Thread(fooThread.ThreadProc);
t.Start();
Thread.Sleep(1000);
Complete = true;
t.Join();
}
}
public class FooThread
{
private Foo foo;
public FooThread(Foo f)
{
foo = f;
}
public void ThreadProc()
{
bool toggle = false;
// while (!foo.Complete) toggle = !toggle;
while (!foo.IsComplete()) toggle = !toggle;
Console.WriteLine("Thread done");
}
}
class Program
{
static void Main()
{
Foo foo = new Foo();
foo.StartThread();
Console.ReadLine();
}
}
A delegate scenario...:
public class Foo
{
public bool Complete; // { get; set; }
private FooThread fooThread;
public Foo()
{
fooThread = new FooThread(this);
fooThread.TriggerCompletion += SetComplete;
}
public bool IsComplete()
{
return Complete;
}
public void SetComplete()
{
Complete = true;
}
public Thread StartThread()
{
var t = new Thread(fooThread.ThreadProc);
return t;
}
}
public class FooThread
{
private Foo foo;
public event Action TriggerCompletion;
public FooThread(Foo f)
{
foo = f;
}
public void ThreadProc()
{
bool toggle = false;
// while (!foo.Complete) toggle = !toggle;
int i = 0;
while (!foo.IsComplete())
{
toggle = !toggle;
i++;
if(i == 1200300) // contrived
TriggerCompletion?.Invoke();
}
Console.WriteLine("Thread done");
}
}
class Program
{
static void Main()
{
Foo foo = new Foo();
var t= foo.StartThread();
t.Start();
Thread.Sleep(1000);
t.Join();
Console.ReadLine();
}
}
These are all contrived examples. But I'm not sure why 1 scenario isn't working.
I only see 2 threads at work here updating a boolean value. So volatile shouldn't be necessary.
Code should reasonably lock free as one or two dirty reads from Foo is OK.
FooThread will signal completion infrequently.
(I'm aware of TaskCancellationSource, this question isn't about cancellations but updating a boolean flag from a different thread via on object instance's method )
EDIT:
Please test in release mode.
EDIT:
Updates on the failing test case i.e. code block 2.
It seems the compiler is making optimizations on !foo.IsComplete() method call. It appears to assume that the instance variable is not used else where so optimizes out the call - perhaps in its simplicity?
By having an instance variable referencing foo the compiler applies to make no such assumption such that the first code block now modified fails:
public class Foo
{
public bool Complete; // { get; set; }
private FooThread fooThread;
public Foo()
{
fooThread = new FooThread();
}
public bool IsComplete()
{
return Complete;
}
public void StartThread()
{
var t = new Thread(()=>fooThread.ThreadProc(this));
t.Start();
Thread.Sleep(1000);
Complete = true;
t.Join();
}
}
public class FooThread
{
public void ThreadProc(Foo f)
{
bool toggle = false;
// while (!foo.Complete) toggle = !toggle;
while (!f.IsComplete()) toggle = !toggle;
Console.WriteLine("Thread done");
}
}
class Program
{
static void Main()
{
Foo foo = new Foo();
foo.StartThread();
Console.ReadLine();
}
}
Also, by introducing an interface on Foo such that the call to foo.IsComplete is now virtual (IFoo.IsComplete) the compiler removes the optimization.
Is this guaranteed though?
It seems to me that the bulk of your question is answered adequately here:
When should the volatile keyword be used in C#?,
and What is the purpose of 'volatile' keyword in C#,
and even Why this program does not go into infinite loop in absence of volatility of a boolean condition variable?
To address some more specific concerns you've expressed…
Should an object reference passed to a Thread be marked as volatile?
Marking the reference in your code example isn't the issue. It's the Complete field that is in question, and which needs to be volatile. The object reference never changes, so making it volatile doesn't matter.
There's a lot of different code in your question, much of the behavior dependent on exact version of compiler, runtime, OS, and CPU type. It's really too broad.
But, the basic question you seem to be asking can be answered simply enough: in the .NET environment, you are required to provide some means of synchronization between threads. All components involved are free to make whatever optimizations they want as long as they comply with the semantics of synchronization you've provided.
If you provide none, the code may or may not work as intended. The runtime is not required to not work when you don't provide synchronization (yes, all those negatives are intended), and so the fact that it does work in some cases even though you don't provide synchronization doesn't in any way absolve you from providing synchronization.
Are delegates affected?
It's not clear what you mean by that. The one example you have above which you describe as "a delegate scenario" doesn't involve any concurrent access to data. Unlike the other examples, the Complete field is only ever accessed by the extra thread you started, so there are no synchronization issues to address.
I only 2 threads at work here updating a boolean value. So volatile shouldn't be necessary
Grammatically confusing statement aside, the volatile keyword isn't a matter of degrees. It works only with primitive types or references (so that the value is a bool is no justification for omitting it), and all you need are two threads for there to be a need for synchronization. Why would you think that having "only 2 threads at work here updating a boolean value" would lead to the conclusion that volatile is unnecessary?
To be clear: that would not be a valid conclusion.

c# locking object shared by public methods and event callback code

Question regarding locking, with text referring to the sample code below...I have a class (Class1) which provides a public List property called Class1Resources. 2 methods in Class1 provide basic query capability on Class1Resources. In addition, Class1 also subscribes to an event from a different service which provides notification that Class1 should update this Class1Resources object.
My question is, what and where should locking be implemented such that the 2 public methods which query Class1Resources are blocked when ExternalAppCallback is executing, thereby ensuring that the query methods are always using the most current data? Is the commented code I have in ExternalAppCallback the proper way to do this?
public class Class1
{
public List<Resource> Class1Resources { get; private set; }
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// do I put the lock here as in the code below?
//lock(someObject)
//{
// Class1Resources = new List<Resource>(updatedResourceList);
//}
Class1Resources = new List<Resource>(updatedResourceList);
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
I'm interpreting your question as "how do I effectively make Class1Resources thread safe?" and so I would recommend either a classic lock or, if you expect writes/changes to be seldom, a ReaderWriterLockSlim. Here is how you'd use a lock in your class to ensure thread safety / consistent data:
public class Class1
{
// Here's your object to lock on
private readonly object _lockObject = new object();
// NOTE: made this private to control how it is exposed!
private List<Resource> Class1Resources = null;
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// Setting a reference is always atomic, no need to lock this
Class1Resources = new List<Resource>(updatedResourceList);
}
// Your new method to expose the list in a thread-safe manner
public List<Resource> GetResources()
{
lock (_lockObject)
{
// ToList() makes a copy of the list versus maintaining the original reference
return Class1Resources.ToList();
}
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
}
Note that in this solution, anything calling the getter of your property will not be using the lock and thus will cause thread safety issues. This is why I changed the code to make it a private member.

Guarantee that a class can only be used by the thread that instantiated it

I've created a class that is not thread-safe and can lead to bad bugs if assumed to be thread-safe. While I work to make my class thread-safe, I'd like to make instances only usable by one thread. Currently my implementation is to check that the current thread is the same as the thread used to construct the instance at every exposure point.
public class NotThreadSafeClass
{
private readonly int _creatorThreadId;
public NotThreadSafeClass()
{
_creatorThreadId = Thread.CurrentThread.ManagedThreadId;
}
public string ExposedProp
{
get
{
AssertSameThread();
return "My Prop";
}
}
public void ExposedMethod()
{
AssertSameThread();
/* Do stuff */
}
private void AssertSameThread()
{
Throw.If(_creatorThreadId != Thread.CurrentThread.ManagedThreadId,
#"NotThreadSafeClass is not thread safe. Please don't use
the same instance of NotThreadSafeClass in multiple threads.");
}
}
Note: Throw.If is defined in http://www.codeducky.org/10-utilities-c-developers-should-know-part-one/
This pattern seems to work, but it's cumbersome and susceptible to bugs if a developer forgets to add this check to any new exposures. Is there a safer and/or more elegant way to ensure that an instance is only used by one thread?
I think that short of using an AOP framework, you will have to "intercept" all such access to your class' methods/properties in your own code, just like you're describing.
I'm thinking Ninject's Interception Extension, or PostSharp
Nothing is built into the language/framework for this.
Cheers
Edit: Moved ThreadLocal<T> to a private field inside the class declaration.
Unless I completely misunderstand, ThreadLocal<T> should meet your needs. An example:
class Foo {
private ThreadLocal<int> _internalState;
public Foo() {
_internalState = new ThreadLocal<int>();
}
public int IntValue {
get { return _internalState.Value; }
set { _internalState.Value = value; }
}
public override string ToString() {
return _internalState.ToString();
}
}
class Program {
public static void Main(string[] args) {
Demonstrate();
}
static void Demonstrate() {
var local = new Foo {IntValue = 5};
Console.WriteLine("Start thread value: {0}", local.IntValue);
new Thread(() => {
local.IntValue += 5;
Console.WriteLine("New thread value: {0}", local.IntValue);
}).Start();
local.IntValue += 10;
Console.WriteLine("Start thread value: {0}", local.IntValue);
}
}
Sample output:
Start thread value: 5
Start thread value: 15
New thread value: 5

Multi-threaded software design

Question, Let's say I had Thread A and Thread B and both of these needed access to a singleton object and it's properties.
Currently the singleton looks as follows.
public class Singleton{
#region fields
private static Singleton singletonObject;
private double value1= 0;
private double value2= 0;
private double value3= 0;
private double value4= 0;
private object locker = null;
#endregion
// private constructor. This will avoid creating object using new keyword
private Singleton() {
locker = new object();
}
// public method which will be called
public void GetName() {
Console.WriteLine("singleton Object");
}
public static Singleton Instance() {
// this object will be used with lock, so that it will be always one thread which will be executing the code
object instanceLocker = new object();
// put a lock on myObject. We won't be able to use singleTonObject becuase it will be null. lock is to make the object thread safe.
// lock can't be worked with null objects.
lock (instanceLocker) {
// check whether the instance was there. If it's not there, then create an instance.
if (singletonObject == null) {
singletonObject = new Singleton();
}
}
return singletonObject;
}
public double Value1 { get { lock (locker) { return value1; } } set { lock (locker) { value1= value; } } }
public double Value2 { get { lock (locker) { return value2; } } set { lock (locker) { value2= value; } } }
public double Value3 { get { lock (locker) { return value3; } } set { lock (locker) { value3= value; } } }
public double Value4 { get { lock (locker) { return value4; } } set { lock (locker) { value4= value; } } }
}
My question. Rather than having thread safe properties, is there a better approach?
Thanks,
Currently your code is completely broken. You're creating a new object to lock on during every call. No other thread will ever know about it, so it's completely pointless.
Don't bother trying to fix it in clever ways. Just initialize it in the static variable initializer:
private static Singleton singletonObject = new Singleton();
Nice and simple.
For more information about implementing the singleton pattern in C# (including using Lazy<T> in .NET 4), see my article on the topic.
Aside from the fact that you're creating a new object to lock on for every call, there is another fundamental problem: even if you do have the same object, you're still not really protecting anything.
Somewhere along the line you initialize Value1 to 9:
Singleton.Instance().Value1 = 9;
Now let's say you have two threads executing this code:
public void Foo()
{
Singleton.Instance().Value1++;
if(Singleton.Instance().Value1==10.0)
{
Singleton.Instance().Value2 = 20.0;
}
else
{
Singleton.Instance().Value3 = 30.0;
}
}
Thread A calls Value1++ and incrementing value1 to 10.0
Thread B calls Value1++ and now the value1 is 11.0
Thread A checks if the value value1 is 10.0 -> returns false!
Thread A sets Value3 to 30
Thread B sets Value3 to 30 also.
This is just a very simple example where locking the properties will not protect you since the external code does nothing to guarantee the order in which things are being read or written. There could be a number of other orders in which Thread A and Thread B are executed which will result in completely different outcomes.
This behavior may be OK, since you could have let the user of the Singleton class take the responsibility for ensuring the correct operation outside your class, but it's generally something you should be aware of. Simply locking the properties will not eliminate the read/write contention.
Are you using .NET 4.0? Instead of locking, you can use ConCurrent collections for thread safe activity.

Usage of the C# lock keyword

I post my understanding of C# lock as follows, please help me validate whether or not I get it right.
public class TestLock
{
private object threadLock = new object();
...
public void PrintOne()
{
lock (threadLock)
{
// SectionOne
}
}
public void PrintTwo()
{
lock (threadLock)
{
// SectionTwo
}
}
...
}
Case I> Thread1 and Thread2 simultaneously try to call PrintOne.
Since PrintOne is guarded by the instance lock, at any time, only
one thread can exclusively enter the SectionOne.
Is this correct?
Case II> Thread1 and Thread2 simultaneously try to call PrintOne and PrintTwo
respectively (i.e. Thread1 calls PrintOne and Thread2 calls PrintTwo)
Since two print methods are guarded by the same instance lock, at any time,
only one thread can exclusively access either SectionOne or SectionTwo, but NOT both.
Is this correct?
1 and 2 are true only if all your threads use the same instance of the class. If they use different instances, then both cases are false
Sample
public class TestLock
{
private object threadLock = new object();
public void PrintOne()
{
lock (threadLock)
{
Console.WriteLine("One");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
public void PrintTwo()
{
lock (threadLock)
{
Console.WriteLine("Two");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
}
And testing code
static void Main(string[] args)
{
int caseNumber = 100;
var threads = new Thread[caseNumber];
for (int i = 0; i < caseNumber; i++)
{
var t = new Thread(() =>
{
//create new instance
var testLock = new TestLock();
//for this instance we safe
testLock.PrintOne();
testLock.PrintTwo();
});
t.Start();
//once created more than one thread, we are unsafe
}
}
One of the possible solutions is to add a static keyword to the locking object declaration and methods that use it.
private static object threadLock = new object();
UPDATE
Good point made by konrad.kruczynski
..."thread safety" is also assumed from
context. For example, I could take
your file opening code and also
generate exception with static lock -
just taking another application
domain. And therefore propose that OP
should use system-wide Mutex class or
sth like that. Therefore static case
is just inferred as the instance one.
Case I: Check ✓
Case II: Check ✓
Don't forget that locking is only one way of thread synchronization. For other userfull methods, read: Thread Synchronization
Straight from MSDN sample:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Process()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Yes and yes. Cases are correct.
Your understanding is 100% correct. So if, for instance, you wanted to allow entry into the two methods separately you would want to have two locks.
Yes, you're correct in both counts.
here are the basics (more or less)
1) use instance locks for instance data
public class InstanceOnlyClass{
private int callCount;
private object lockObject = new object();
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
2) use static locks for static data
public class StaticOnlyClass{
private int createdObjects;
private static object staticLockObject = new object();
public StaticOnlyClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
}
3) if you are protecting static and instance data use separate static and instance locks
public class StaticAndInstanceClass{
private int createdObjects;
private static object staticLockObject = new object();
private int callCount;
private object lockObject = new object();
public StaticAndInstanceClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
based on this your code is fine if you are accessing instance data but unsafe if you are modifying static data

Categories

Resources