简体   繁体   中英

Are static methods that creates a new instance of it's object thread safe?

From what I've read on other SO posts, my guess is that neither CreateTry1 nor CreateTry2 are thread safe, but even after reading so much, I'm still not 100% sure this is correct.

public ClassA
{
  private string MyString;

  private ClassA(string myString)
  {
    MyString = myString;
  }

  public static CreateTry1(string aString)
  {
    return new ClassA(aString);
  }

  public static CreateTry2(string aString)
  {
    ClassA a = new ClassA();
    a.MyString = aString;
    return a;
}

// The Below is not the main focus of the question
static public void Main(String[] args)
{
  Thread t1 = new Thread(p =>
  {
    int i = 0;
    while(i < 1000000)
    {
      ClassA newA = ClassA.CreateTry2("Hello");
      i++;
    }
  });

  Thread t2 = new Thread(p =>
  {
    int i = 0;
    while(i < 1000000)
    {
      ClassA newA = ClassA.CreateTry2("Hello");
      i++;
    }
  });

  t1.Start();
  t2.Start();
}

More Information 1: Clarification

I edited the code

This question was specifically pertaining to Selenium Grid. I thought if I got a better understanding of what was and was not thread safe (in general) then I would know what to avoid unsafe code when refactoring code to run in Selenium Grid (in parallel). However, I think I jumped into the deep end of the pool, and don't fully know how to swim here, so apologies for that.

I thought part of the answer would be something as simple as, "Non-Static variables (fields and properties) within a non-static class are Always thread safe. Static variables (fields and properties) inside a non-static or static class are not safe in general".


More Information 2: Related SO posts

I read a lot of posts. Some statements cleared things up while others made things more confusing.

This comment made most sense . However, part of the statement says, "When your data in separate instances still gets mixed up, it's most likely because the data is not really separate." It seems hard to not see that one of your variables (fields) was static, so wondering how else this cross contamination of data between threads could have occurred withOut him knowing.

Any conversation related to the following MSDN statement never fully made sense to me:

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

1. About above quote

2. About above quote . This was a good question, but the answers at first seemed overly complex. I eventually remembered that 'members' refers to fields, properties and methods within a class (not just fields). A statement this broad would make the answers complex.

The following post, "Is this extension method thread safe" , was a great question but I couldn't figure out which answer was correct. I believe both reposes are correct, but Avner's is a very general answer and Ondrej's specifically answers the question.

A few posts, like this one , brought up the term 'shared state' which, after reading the following , seemed to be nothing more than a static field within a class (but I could easily be wrong).

I'm not sure what you're trying to figure out, but I guess knowing two things may help:

  • CreateTry1 and CreateTry2 don't access shared data. MyString property is not shared among instances. So the methods are thread-safe.
  • Constructors are guaranteed to be thread-safe. Multiple instantiations of ClassA in parallel don't interfere with each other ie are thread-safe.

Are static methods that creates a new instance of it's object thread safe?

No. That is not a sufficient and necessary condition for thread-safety.

Take this as a counter example to your question:

public class Foo
{
    public int Value;
    private Foo()
    {
        this.Value = magic;
    }
    private static int magic = 42;
    public static Foo CreateFooIncrement()
    {
        magic += 1;
        return new Foo();
    }
    public static Foo CreateFooDecrement()
    {
        magic -= 1;
        return new Foo();
    }   
}

It is certainly possible that instances of Foo might be created with an unexpected Value based on concurrent calls to CreateFooIncrement and CreateFooDecrement .

This example class Foo has static methods that create instances of its own class and it is definitely not thread-safe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM