Returns a link from a static method thread safe?

I have a class:

class PrintStringDataBuilder { PrintStringDataBuilder() { } public static GetInstance() { return new PrintStringDataBuilder(); } //other class methods and fields, properties } 

Available from client code as:

 PrintStringDataBuilder instance = PrintStringDataBuilder.GetInstance(); 

Is surveillance stream safe?

Edit: just try not to write PrintStringDataBuilder builder = new PrintStringDataBuilder (); several times in the asp.net mvc web application. There are no other static methods, static fields, or static properties in the PrintStringDataBuilder class.

+8
multithreading c #
source share
4 answers

Yes? Without knowing the internals of the constructor of this class, you can say that calling GetInstance() was thread safe. Any methods in this instance do not guarantee that they will be thread safe, especially since you have not provided any of these methods.

This is simply called a factory pattern.

EDIT: if you are trying to return a singleton, you can do it like this:

.NET 4+

 private static Lazy<PrintStringDataBuilder> _instance = new Lazy<PrintStringDataBuilder>(() => { return new PrintStringDataBuilder(); }); public static PrintStringDataBuilder GetInstance() { return _instance.Value; } 

.NET 3.5 and below

 private static PrintStringDataBuilder _instance = null; private static object _lockObject = new object(); public static PrintStringDataBuilder GetInstance() { if(_instance == null) { lock(_lockObject) { if(_instance == null) _instance = new PrintStringDataBuilder(); } } return _instance; } 
+11
source share

In the threadsafe section, are you worried that multiple threads calling your static method are going to get SAME PrintStringDataBuilder? The answer to this question is “NO” and the call is thread safe.

Having said that, no one can tell from the small fragment that you give, the rest of the class, or its constructor. There are many reasons why class instances are not thread safe. if they refer to static properties without blocking, this is an example.

+5
source share

Method input is always thread safe. Access to shared data may not be available. Thus, this code is thread safe because there is no shared data.

If your intention here is to have one PrintStringDataBuilder instance for all threads, then your code will not work for this purpose. You need the right singleton. In .NET 4, code can be very compact:

 private static Lazy<PrintStringDataBuilder> instance = new Lazy<PrintStringDataBuilder>(); public static PrintStringDataBuilder Instance { get { return instance.Value; } } 

This ensures that in each stream of PrintStringDataBuilder.Instance the same and only one instance of your PrintStringDataBuilder object will be indicated, which will be created in a lazy way, i.e. only when it will be used for the first time and will not be earlier.

+3
source share

@Tejs,

Actually, in .NET you do not need to use the double check locking mechanism - there are better ways around it. But if you decide to do this, your double-check lock implementation is incorrect and not truly thread-safe. The compiler can optimize initialization _instance = new PrintStringDataBuilder(); - There are 3 possible modifications to make your example truly thread safe:

  • initializing a static inline member is definitely the easiest one!
  private static PrintStringDataBuilder _instance = new PrintStringDataBuilder; public static PrintStringDataBuilder GetInstance() { return _instance; } 

2. Use the "volatile" keyword to ensure that the initialization of PrintStringDataBuilder not JIT optimized.

 private static volatile PrintStringDataBuilder _instance = null; private static object _lockObject = new object(); public static PrintStringDataBuilder GetInstance() { if(_instance == null) { lock(_lockObject) { if(_instance == null) { _instance = new PrintStringDataBuilder(); } } } return _instance; } 

3. Use Interlocked.Exchange with double check locking:

 private static PrintStringDataBuilder _instance = null; private static object _lockObject = new object(); public static PrintStringDataBuilder GetInstance() { if(_instance == null) { lock(_lockObject) { if(_instance == null) { var temp = new PrintStringDataBuilder(); Interlocked.Exchange(ref _instance, temp); } } } return _instance; } 

Hope this helps.

+1
source share

All Articles