Are class variables in Java shared between threads or not? - java

I was wondering when declaring a class variable (i.e. a variable declared outside a method) would potentially cause problems in a program that's executed by several threads. I suppose finals are save to use (i.e. not shared), and static variables are definitely shared between threads. But what about "standard" variables? When are they shared and when are they "private" to each individual thread?
Update: While I accept that local variables (within methods) are not shared and class variables usually are I would love to understand why that is (from a technical point of view). So any explanation to that effect (or links to articles that are fairly easy to understand) would be much appreciated.

Java provides the ThreadLocal<T> class to declare variables that are not shared between threads. Non-final parameters and local variables are also not shared between threads. final parameters and locals variables may be shared between threads when they are used in an anonymous class definition, but this shouldn't be a problem since they are final. In all other cases I can think of, variables can be shared between threads.

The short answer is, any method or variable, both static and non-static, has the potential to be accessed by more than one Thread if its access modifier makes it visible to that Thread.
The concept of "thread-safe" is entirely different. If a variable is read-only (final can be used to make primitives read-only, but only makes references to objects immutable, not the objects themselves), multi-threaded access of that variable is inherently thread-safe. If it can be written to, the proper use of synchronized blocks or the volatile keyword is necessary to ensure mutual exclusion.

There's nothing special about a standard variable that shields it from multi-threaded access and resulting problems. That's up to YOU the programmer to worry about.
If two threads need to safely access the same instance fields, then YOU have to write code to manage that.
Some common techniques are to use synchronized blocks to manage mutability, using atomic or final primitives (a final Object is not necessarily safe unless you know the Object isn't mutable), or simply use a ThreadLocal to give each thread its own unshared instance of the class.

Final doesn't mean 'not shared' just that the field cannot be overwritten, it can only be initialized one.
Static behavior is also not related to threading, static means that the field has a Class scope and not instance scope, meaning it's shared by all the instances of a Class.
If you want to protect a field from being modified by many threads, you have to manipulate it through synchronized methods.

Such variables are called the fields of the class, and they are definitely not "thread-safe" in general, even when they are final (because final only refers to the reference itself, not what's inside the object).

Related

Does volatile propagate to instance members?

Suppose there is some simple container declared and instantiated like this
class Test {
private volatile List<Object> list = new ArrayList<>();
}
, and reads and writes to it are guarded by locks; synchronized keyword not used. Although Test.list is declared volatile, none of its member fields like ArrayList.elementData also bear this modifier. Now, in multithreaded application, will it behave like volatile container? In other words, will changes submitted to ArrayList.elementData by some thread be visible immediately by all other threads?
The general answer is no: volatile only establishes a happens-before relationship between reads and writes to the reference variable. If two threads concurrently access an inner field of the object referenced in the variable, there still needs to be a synchronization mechanism.
In your case, the best approach seems to use a synchronized list, or some wrapper from the java.util.concurrent package.
Short answer: no. As a consequence, array elements are always non-volatile (even if the array itself is declared volatile). You need to use special concurrent-friendly implementation of the List. Usually java.util.concurrent.CopyOnWriteArrayList fits the needs. If you assign the list variable only once, then volatile keyword does not change anything (in this case better to use final).

It is required synchronized keyword for non void method?

If method have return type and it is access by two or more thread then it is required to use synchronized block or keyword with this method?
No. If that method does changes any of the field of the object that its operating upon (i.e. changing the state of object) and same object is shared amongst two thread then you might need it.
You may need to use synchronized when you are reading fields which can be changed in another thread, or writing fields which might be read in another thread. There is no specific rule of when you must, or must not use synchronized or the language would be able to do this for you. It is up to you to decide based on you use case.
It is not required. For example, if your class does not offer methods which modify instances of this class (then the class is said to be immutable) you don't need to synchronize.
However, as soon as at least one thread can write to some member variable, and there exist other threads which can read from or write to this variable at the same time, you need to synchronize the access to this variable, either by using the synchronized keyword or by manipulating locks explicitly. In some cases, you might also use atomic operation (AtomicInteger, for example).

Optimizing Java worker speed-wise

I've got a Java worker that handles a lot of data. It waits on a Redis queue in main() and then calls different functions to handle the data depending on type.
I've got two questions on optimizing the code:
Would it be better to have private static class variables and use them to send data to methods instead of using function arguments?
Would it speed up execution time if variables used in these often-called methods would be private static on class instead of declared always over again when entering the method?
Thanks
You are talking about speed, but static variables will help you mostly memory-wise.
If you are creating multiple instante variables (non-static fields) and thinking of changing to into a static one:
When multiple instances of a class need access to a particular object in a variable local to those instances (instance variable), it is better to make that variable a static variable rather than have each instance hold a separate reference. This reduces the space taken by each object (one less instance variable) and can also reduce the number of objects created if each instance creates a separate object to populate that instance variable. (Quoted from Java Performance Tuning book.)
If you are not creating instance variables, but just passing a variable along in parameters:
Performance-wise, there should be no difference. As a all method parameters in Java are passed value-by-reference, meaning that the actual variable is not copied over an over: only its address (pointer - a reference to the variable) is copied into the parameter of the called method.
In any case, static fields can compromise your code's readability (it can make them so much harder to maintain). If you really need a static behaviour, please also consider using a Singleton design pattern.
Bottom line is:
Seems to me your scenario is: You are just passing variables along (an not having instance variables).
I advise you to keep it that way. If you change it, there will be near-zero (if any) performance gain by using static fields -- on the other hand, your code will be much harder to maintain/understand/debug.

Why there is no local static variable in Java?

In C/C++ we use static local variables for maintaining a method's state. But why it is not supported in Java?
Yes, I can use an static field for this purpose. But isn't it a bit weird to create a field for maintaining only one method's state?
You have found the only solution.
Java dropped a number of complexities from C++, and this was one of them.
Static variables scoped to a function do nasty things to you in concurrency (e.g. strtok is a famously nasty one to use with pthreads, for exactly this reason).
In general, what you want is an object with state. The function in question should then have an object-level variable. Then you can create instances that each maintain state.
Much easier to understand/maintain/etc.
If you truly need to maintain state as a singleton, then static fields are it.
The Java language spec doesn't seem to defend the omission of variables that correspond to C static variables.
Hiding state in class methods has a few drawbacks when seen from a Java perspective. Generally the existence of a function-level static variable isn't the sort of implementation detail that you'd want to expose outside of that function.
But the method's state is actually part of the class's state, and method-level static variables would have to be serialized / deserialized any time the object is persisted. This might not sound common, coming from a C background, so I'll note a few common examples.
Application server clusters can pass user session objects between nodes in order to provide fault tolerance.
JAXB could be used to marshall an object into an XML document
JPA can be used to persist object state to a database
If the variable's value is worth saving when the object is persisted, then there's a good chance that code outside of that class will need to reference that value. And suddenly that means defining access levels -- is a static variable in a public method automatically public? Or would a programmer have to declare it so?
We also have to think about extensibility. Would derived classes be required to implement the same static variable? Or would there be a reference to the variable from the function in the base class?
It's more likely that the C method that would use a static local variable would be a good candidate for a class in Java. It has state and hopefully exists for a single purpose. There's little drawback to encapsulating the functionality into an object, and it makes for a cleaner separation between transient values (such as local variables) and more long-term state.
Some of the other answers show why you might not want to have this. But you can also ask why from a historical perspective.
To answer this you have to start to see why C does have static local variables. C has much fewer means than Java and C++ to limit the scope of a variable, the only options for static data are 'inside the file' and 'everywhere'. So this provides an extra layer, to limit the scope.
An important aspect of C++ is compatibility with, so it is allowed in C++ as well. But it doesn't need local static scope as much anymore, because there are many other means to limit scope of static data. The use is not popular in (modern) C++.
Java merely takes a lot of inspiration from C/C++, it didn't have to worry about backwards compatibility, so it could be left out.
Perhaps because methods are not objects in Java; so maintaining their state as you said make not much sense and I guess you'd have to create a new concept in the byte code for that; use an object as Tony K. said.
instance methods are invoked by the instance(objects) of the class . Static things belongs to the class not to the object that's why local variables are not static.Instance variables are static and they can also initialized at the time of class loading by static blocks.
enter image description here
for more information please visit :- https://www.youtube.com/watch?v=GGay1K5-Kcs&t=119s

In Java, do methods that don't use static or class variables need to be synchronized?

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 ?
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.
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.
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. )
You do not need to worry about local variables. Instance variables however are something to care about.

Categories

Resources