In Java, do methods that don't use static or c

2019-04-26 20:57发布

问题:

Do methods that only use local variables inside suffer any threading issues ?. Somewhere it was mentioned that the method with local variables are copied to each thread stack frame to work with and do not need to synchronized for multithreaded implementation unless it uses class level or static references/variables ?

回答1:

If your method only operates on parameters and locally-defined (as opposed to class member) variables then there are zero synchronization problems to worry about.

But...

This means any mutable reference types you use must live and die only within the scope of your method. (Immutable reference types aren't a problem here.) For example this is no problem:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  return working_set.doSomethingElseAgain(interim);
}

A MyObject instance is created within your method, does all of its work in your method and is coughing up blood, waiting to be culled by the GC when you exit your method.

This, on the other hand, can be a problem:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  another_interim = doSomethingSneaky(working_set);
  return working_set.doSomethingElseAgain(another_interim);
}

Unless you know for sure what's going on in doSomethingSneaky(), you may have a need for synchronization somewhere. Specifically you may have to do synchronization on the operations on working_set because doSomethingSneaky() could possibly store the reference to your local working_set object and pass that off to another thread while you're still doing stuff in your method or in the working_set's methods. Here you'll have to be more defensive.

If, of course, you're only working with primitive types, even calling out to other methods, passing those values along, won't be a problem.



回答2:

Does methods that only use local variables inside, do not suffer any threading issues ?

True in a very simplistic sense, but lets be clear - I think this is only true if:

  • such a method uses only local variables that are primitives or references to mutable instances that cannot otherwise be accessed outside the method by any other means.

  • such a method invokes only methods that are thread-safe.

Some ways these rules could be violated:

  • A local variable could be initialized to point to an object that is also accessible outside the method. For example, a local variable could point to a singleton (Foo bar = Foo.getSingleton()).

  • A local instance held by a local variable could "leak" if the instance is passed as a argument to an external method that keeps a reference to the instance.

  • A class with no instance variables and with only a single method with no local variables could still call the static method of another class that is not thread-safe.



回答3:

The question is very generic, so please do not expect any specificity from my answer.

1_ We need to more careful with static methods than say instance methods.

2_ @Justmycorrectopinion is about right, but some of the terms he described needs to be more elaborated to be perfect. ( Even if the static method, only works on local variable, there is still possibility of race condition.)

3_ For me there are simple rules that have helped me analyze thread safety.

Understand if each components encapsulated within it is shareable or not. So the simplest solution is to reduce the scope of all variable and only increase scope if absolutely necessary and if component perform mutation on a object, its usually not thread safe.

4_ Use tooling support to perform static code analysis on thread safety. (Idea has checkthread plugin).

5_ Never use static method to perform object mutation. If calling static variable causes object mutation, then the developer is just circumventing OOPS.

6_ Always document thread safety. Remember some method may not need to be synchronized when you develop, but can be made not thread safe very easily.

7_ Last but probably my most important point, make sure most of your objects are immutable. In my experience, most of the time, I never had to make many of my objects mutable. (In rare cases when object state needs to be changed, defensive copying / New Object Creation is almost always better. )



回答4:

You do not need to worry about local variables. Instance variables however are something to care about.