I have my singleton as below:
public class CurrentSingleton
{
private static CurrentSingleton uniqueInstance = null;
private static object syncRoot = new Object();
private CurrentSingleton() { }
public static CurrentSingleton getInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
uniqueInstance = new CurrentSingleton();
}
}
return uniqueInstance;
}
}
I would like check, if I will have two thread, are there two different singletons? I think, I shall have two different singletons (with different references), so what I'm doing:
class Program
{
static void Main(string[] args)
{
int currentCounter = 0;
for (int i = 0; i < 100; i++)
{
cs1 = null;
cs2 = null;
Thread ct1 = new Thread(cfun1);
Thread ct2 = new Thread(cfun2);
ct1.Start();
ct2.Start();
if (cs1 == cs2) currentCounter++;
}
Console.WriteLine(currentCounter);
Console.Read();
}
static CurrentSingleton cs1;
static CurrentSingleton cs2;
static void cfun1()
{
cs1 = CurrentSingleton.getInstance();
}
static void cfun2()
{
cs2 = CurrentSingleton.getInstance();
}
}
I suppose that I should got currentCounter = 0
(in this case every two singleton are different - because are creating by other threrad). Unfortunately, I got for example currentCounter = 70
so in 70 cases I have the same singletons... Could you tell me why?
I would like check, if I will have two thread, are there two different singletons
No, there are not. A static
field is shared across each entire AppDomain
, not each thread.
If you want to have separate values per thread, I'd recommend using ThreadLocal<T>
to store the backing data, as this will provide a nice wrapper for per-thread data.
Also, in C#, it's typically better to implement a lazy singleton via Lazy<T>
instead of via double checked locking. This would look like:
public sealed class CurrentSingleton // Seal your singletons if possible
{
private static Lazy<CurrentSingleton> uniqueInstance = new Lazy<CurrentSingleton>(() => new CurrentSingleton());
private CurrentSingleton() { }
public static CurrentSingleton Instance // use a property, since this is C#...
{
get { return uniqueInstance.Value; }
}
}
To make a class that provides one instance per thread, you could use:
public sealed class InstancePerThread
{
private static ThreadLocal<InstancePerThread> instances = new ThreadLocal<InstancePerThread>(() => new InstancePerThread());
private InstancePerThread() {}
public static InstancePerThread Instance
{
get { return instances.Value; }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With