How does the JVM handle final variables differently under the hood?
There is at least one section in the JVM specification about final's impact on the memory model, and it is quite important for multi-threaded code:
final fields of an object allow "safe publication":
When a constructor exits, all final fields must be visible to all threads.
The fields on any object accessed via a final reference are also guaranteed to be at least as up to date as when the constructor exits.
Taken together, this means that immutable objects (ones where all fields are final and are either primitives or references to immutable objects) can be concurrently accessed without synchronization. It is also safe to read "effectively immutable" objects (ones whose fields aren't actually final, but in practice never change) via a final reference.
Conversely: If your object is accessed by multiple threads, and you don't declare its fields final, then you must provide thread-safety by some other means.
But note that the JVM does not enforce actual finality: You can re-assign values using reflection (which of course undermines the safe publication).
Related
I know the prerequisites for a class to be made immutable. I looked into the code, there were no setters for any variable defined in String. For StringBuffer and StringBuilder, there were two setters:
setLength which called the same named setters of parent AbstractStringBuilder.
setCharAt which manipulated the char value[] of parent AbstractStringBuilder.
String is "immutable" because its API (the public methods it defines) provides no way for a caller to change its state. Other classes, like StringBuilder, are mutable because they do provide "mutators", or methods that change the state of the class.
Under the covers there's nothing different between mutable or immutable objects. An object is just the primitive and reference values that make up its fields, and all fields are conceptually mutable (ignoring the final keyword for the moment). But by restricting the visibility of these fields (e.g. making them private) and defining methods that limit what a caller can do (like defining a getter but not a setter) you can provide a guarantee that instances of the class will be immutable, which is to say you promise none of its fields (or the objects they reference) will change over its lifetime.
By using the final keyword you can be even more explicit that a class is immutable. If you simply don't provide mutator methods, it's still possible for a class to be mutable if some private method mutates the class. If all the fields in a class are marked final, that's not (normally) possible. You can be confident any class with only final primitive (or immutable) fields is immutable*. That isn't the only way to guarantee immutability, but it is the clearest - any attempt to mutate the class would be a compiler error.
* The class itself also has to be declared final, otherwise someone could potentially create a mutable subclass. But again, there are other ways to ensure immutability. Using final everywhere is just the easiest to see.
There are a lot of things here.
All fields are private.
There are no setters / mutators.
Construction injection of arguments (using which String has to be constructed).
Reference to underlying char array (char[] value) does not leak out of this class.
Mutability is not merely defined by the presence or absence of setter/mutator methods.
In the case of StringBuilder and StringBuffer, there's a plethora of other methods (e.g. all the append() methods) that alter the internal state of the object, and hence make it mutable.
If I need to declare just some constants to use in my class, and there is no real need for declaring them as static, i.e. there will no be several instances sharing that member, is there any sense to declare them as static? Is there a "cost difference" between using static and instance members? Please give information about both java and C#.
And also, is there a difference between java's static members and C#'s static members?
I need to declare just some constants to use in my class
No Idea about Java but in C# constant member's are implicitly static in nature.
See MSDN Document: Constants (C# Programming Guide) for more information. Quoting from the referred document:
Constants are accessed as if they were static fields because the value
of the constant is the same for all instances of the type. You do not
use the static keyword to declare them.
I generally declare every constant in my applications as a private static final variable, for a number of reasons.
Consistency. It's clear to myself and others what are the default core constant definitions are in my application. I can keep them all grouped together, and it's very easy to navigate over to them if they need to be modified. Because they're static, these changes ripple down through every call. This safegaurds you from making accidentally multiple definitions of the same constant.
Performance. If I have a constant that's never changed, there's no point in constantly allocating memory for it during a method call. It's allocated once when a reference to the class is made, and then you're done with it. There that memory remains references until all references to the class are done with.
Good practice. There's a convention in programming where dependencies of should be as highly decoupled as possible. When you declare a function or variable as static, you enforce that it must be interacted with in a static way, i.e. independently of a runtime instance. Without this dependency of a class encapsulating member variables at runtime, you can more precisely control interaction with that class, because it ensures you define precise rules on how a class can be interacted with. You find that the more constants and methods you can declare as static, the more flexible your software becomes because there's little confusion over how certain values and behaviours are supposed to be manipulated.
Exposure. Some functions or constants you define may be useful to other parts of your application. This means you can take advantage of functionality without the requirement for using a runtime instance. For example, the quadratic formula is the same everywhere, so why should it belong to a single instance at all? The same goes for constants, like the speed of light.
Personally, I always declare all functionality of my application as private static. If it makes sense for a class to use that functionality as part of it's operation, then the programmer can wrap the method call in another method and provide the appropriate member variable data. If another part of your application needs to use that static function, all you need to do is increase the visibility of the function.
In Java, constants are not implicity static; constants are not an actual language specification, so constants in Java are simply variables that we refer to as constants.
In C#, constants are implicitly static. Constants are part of the language specification, and states in the documentation:
Constants are accessed as if they were static fields because the value of the constant is the same for all instances of the type. You do not use the static keyword to declare them.
if you will declare constant as static than your program will use only one memory location to store this constant value, and if you will not use static than every object will store this constant separately. As you said there are no several instances, in this case either you specify constant as static or declare it simply both will be of same cost.
Is it safe to say that an object is thread-safe in Java if its class contains no instance variables that can be changed and no static variables?
Totally safe, as long as it does not extend a non thread-safe class.
If an object is stateless, it can safely be shared by several threads.
That is also why it is encouraged to use immutable objects in multi-threaded environment as their state cannot be concurrently modified.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This made little sense to me as each thread's stack is confined to that thread alone. So it is already 'threadlocal', right ?
Why then do we need ThreadLocal ? - On further reading, I confirmed my assumption from various sites (a majority of which fail to provide these facts or contradict each other) that this is indeed applicable for static fields.
Which does make sense.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields ? (I came across some sites that say 'ThreadLocal' is "mainly" used for static fields; even https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html uses the word "typically")
I think that this Question is based on a false premise.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This is not what "global" really means. Global really means accessible to the entire program without any qualification. And in fact, Java doesn't have true global variables. The closest it has is "public static" fields ... which are accessible with qualification.
But back to the Question ...
A threadlocal variable is available to a method if two conditions are satisfied:
The method call must be on the correct thread. (If it is on a different thread, it sees a different variable.)
The method must be able to get hold of the ThreadLocal object that effectively "declares" the thread local variable (in any thread).
Does the 2nd condition imply that the "declaration" is global?
IMO, no. For two reasons.
Global variables in the conventional sense have only one instance. A thread local has a distinct instance for each thread.
The fact that the ThreadLocal is accessible to a specific method does not make it accessible to any method. The normal (and good practice) usage pattern for a ThreadLocal is to hold the object reference in a private static variable. That means that methods in the same class can use the corresponding thread local variable instances ... but methods in other classes can't.
Now it is possible to put the reference to ThreadLocal in a public static variable, but why would you do that? You are explicitly creating a leaky abstraction ... which is liable to cause problems.
And of course, you can do what #Radiodef's answer shows; i.e. create a thread local whose instances are only accessible from methods on a specific instance of a specific class. But it is hard to understand why you would want / need to go to that level of confinement. (And it is liable to lead to storage leaks ...)
Short answer: if you don't want your thread local variables to be accessible, restrict access to the ThreadLocal object.
Only local variables are on a thread's stack.* Static variables and instance variables both live on the heap. If we wanted to, we could also just pass a ThreadLocal around by itself without it ever living inside an object or class.
We could view ThreadLocal as a local variable which could be accessible at any point in time.
Normal local variables are destroyed when the scope they are declared in returns, but a ThreadLocal can live anywhere.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields?
We can make one up...
interface Dial {}
class Gadget {
ThreadLocal<Dial> d = new ThreadLocal<>();
}
class Gizmo implements Runnable {
Gadget g;
Gizmo(Gadget g) {
this.g = g;
}
public void run() {}
}
{
Gadget g = new Gadget();
new Thread(new Gizmo(g)).start();
new Thread(new Gizmo(g)).start();
}
Both threads share the same instance of Gadget but has their own local Dial.
Why then do we need ThreadLocal?
The truth is we don't need ThreadLocal very often, if at all.
* Only local variables are on a thread's stack except in the case of a theoretical optimization the JVM is allowed to do where objects can be stack allocated. We would never find out about this if it happened because it would not be allowed to change the behavior of the program. If an object is shared between threads, it's on the heap.
static ThreadLocal<Whatever> threadLocal;
Declares a field that points to an instance of class ThreadLocal. Each Thread has a Map<ThreadLocal<?>, Object> that associates instances of ThreadLocal with the value the corresponding "thread local variable" has for this Thread. That is, each ThreadLocal instance identifies a "thread local variable", and as far as the JVM is concerned, ThreadLocal is a class like any other.
Usually, when we need a "thread local variable", we only need a single one, and therefore create only a single ThreadLocal instance, which is often kept in a static field for convenient access.
If we need a new "thread local variable" for every instance of the host object, we could simply create a new ThreadLocal instance for every host object, and store in an a non-static field. Off hand, I can't think of a case where this is the simplest solution, but we could do it.
Threadlocal is a container for a set of variables each one of which is only available to one thread, ie it provides an instance of the contained class for each thread. So the ThreadLocal object is globally available (spending on permissions) but each instance of the contained class is only locally available to the thread.
This means that it needs to be initialized and destroyed for each thread slightly differently but in all other ways it is the same as any other variable.
Note : The point of destroying instances is to prevent memory leaks or leakage of state between independent invocations on the same thread if threads are being drawn from a pool.
Thread local variables are often used to provide a thread safe option for storage where there is no need for communication between threads. One such example is to define a new scope in CDI where that scope will exist wholly within a single thread (eg you could define an asynchronous request scope).
As such there is no need to restrict it to static or non-static variables as long as it is accessible where it is needed. In a default java environment Static variables are a convenient way of providing such access but in CDI a Singleton bean can provide the same level of access with many advantages.
In the injected singleton case the singleton bean would contain a nonstatic reference to the ThreadLocal and provide services to access the instances contained therein. Both the references to the injected singleton and the singleton's reference to the ThreadLocal would be non static.
I have doubt a doubt regarding making an immutable class.
As per the java docs.
I made the class final( no one can extend)
field are private.
no setter function.
If fields are mutable then send a cloned copy of the field.
My doubt is that its compulsory to make a field of my class as final?
If there are no setter methods (and presumably no other methods to affect the fields' values) and the fields themselves are private, marking them as final is somewhat redundant.
Having said that - its a good defensive practice which many projects' standards follow.
Although as many say its not mandatory to mark the fields as final I would say atleast in one case that I can think of you need to mark the fields as final and that is in the case if you want to make your immutable class thread safe.
According to Java memory model:-
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
JLS final thread safety
So if you have an immutable class with instance variables which you initialize in constructor as non final variables then there is no guarantee of thread safety as the writes to the non final variables may not be visible to other threads even though the constructor has fully run ( Note recreating this is very difficult as this may occur in a highly concurrent application)
Immutable = not changeable. So making properties final is a good idea. If not all properties of an object are protected from being changed I wouldn't say the object is immutable.
BUT an object is also immutable if it doesn't provide any setters for it's private properties.
An immutable object will never change, but anything that it refers to might change.
Deep immutability is much stronger: neither the base object nor any object you can navigate to from it will change.