I have a question regarding the Java "volatile" keyword:
Assume, we have the following Class:
public class BooleanValClass {
private boolean bolVal = false;
public boolean getVal() {
return this.bolVal;
}
public void setVal(boolean val) {
bolVal = val;
}
}
Now, assume a Thread is using this class with a "volatile" keyword:
private volatile BooleanValClass myClass = new BooleanValClass();
Do i have to attach the "volatile" keyword also to the member field "bolVal" of class "BooleanValClass" or is the "volatile" of the object reference some kind of "redirected" to all members of the class "BooleanValClass"?
Thanks,
Tom
Nothing is redirected. myClass is volatile, bolVal is not. Assignments and reads from myClass work as volatile. Assignments/reads to/from bolVal don't.
In Java reading and writing fields of all types except long and double occurs atomically by JVM, and if the field is declared with the VOLATILE modifier, even long and double are become read and written atomically. Atomic garantee, that we get 100% either what was in variable, or what will calculated in variable, nor can there be any intermediate result in the variables.
Related
Non-static final variables can be assigned a value only once.
But why this assignment can happen only either within a declaration or in the constructor?
A final variable is defined to be immutable i.e., the value assigned to it will be the one and only for that variable x. As one can read from the JLS(§4.12.4.)
A variable can be declared final. A final variable may only be
assigned to once.
Now the constructor is just like any other method, except that it is the one that gets executed first when an object (non-static) is created from the class.
Hence, final variables can be assigned through constructors.
For example take the following code:
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
}
Compiler accepts this invocation because it is guaranteed that for that particular object its class's constructor gets invoked first and doesn't invoked again (i.e. constructor gets invoked one and only one time during the entire lifetime of object.)
However following code throws error: Non-static field 'x' cannot be referenced from a static context
public class Test {
public final int x;
static {
x = 5;
}
public Test(int x) {
this.x = x;
}
}
Since x is not a static field, it cannot be initiated within a static block.
This code would also throw error: Cannot assign a value to final variable 'x'
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
public void setX(int x) {
this.x = x;
}
}
That is because it is not guaranteed for this object, that the method setX would run first and only once. The programmer could call this method multiple times. Hence, the compiler throws an error.
So there is no way to make a variable "initializable" only once (e.g.,
a setter would block if variable was already assigned before) solely
with java syntax? I thought final might work this way but now I see
it's not.
For your question, you could simply make a variable private and add the condition to the setter method to add value only if variable is null.
For example:
public class Test {
private Integer x;
public Test() {
}
public Test(int x) {
this.x = x;
}
public void setX(int x) {
if (null == this.x) this.x = x;
}
public static void main(String[] args) {
Test y = new Test(5);
System.out.println(y.x);
y.setX(20);
System.out.println(y.x);
}
}
This is not thread safe by the way. I just added a simple example.
What does the keyword final mean in Java?
When used in a class declaration, it means that the class cannot be extended.
When used in a method, it means that the method cannot be overridden.
When used in a method parameter, it means the value of such parameter cannot be changed inside the method. (local constant)
When used in a class field ("variable), it means that it is a global constant.
Values for constants must be resolved at compile time. And, as the word implies, constants fields cannot change value. Therefore, the compiler does not allow the value to be set from a setter (mutator) method.
Contrary to what many believe, for a field to be constant, it does not have to be declared static and final. That said, since the value of a constant cannot be changed, each class instance will share the same value. Therefore, explicitly making them static reenforces this notion.
There is a fifth use of the keyword final and this is when used when local variables are declared. This is a more lengthy explanation.
What happens when you compile code?
I updated my answer because I think part of the problem is that some developers don't quite understand what happens when the code is compiled. As I mentioned before, constant values are resolved at COMPILE TIME. To understand this concept, consider the following example:
public class MyClass {
private final double PI = 3.14159;
// rest of class left out intentionally
}
If I compile this class on my laptop and then I deploy the code to some remote server, how does the server know that the global constant field PI has an assigned value of 3.14159? This is because when I compile this code, this value gets packaged with the byte code. The class constructor doesn't come into play at all in this case. HOWEVER, if the constant field is initialized to its DEFAULT value, then permanent (constant) value may be assigned via the constructor
public class MyClass {
private final double PI; // default value of 0.0
public MyClass(double value) {
PI = value;
}
// rest of code omitted intentionally
}
Here's where declaring a constant as static makes a difference. If a constant is also static, you can't do the above because calling a constructor implies that you can have multiple instances of MyClass and each instance could set a different value. This is clearly a violation of what a static member is. So, if you MUST declare a field as both static and final, understand that you cannot assign a value using this second approach. Only the first one I showed is allowed.
Final Stop's a Variable’s Reassignment
a short simple answer:
Use the keyword final when you want the compiler to prevent a variable from being re-assigned to a different object.
Whether the variable is a static variable, member variable, local variable, or argument/parameter variable, the effect is entirely the same.
Hope this helps friend =)
#StaySafe
Consider the following non-traditional implementation of double-check locking that does not use volatile:
public class ValueProvider {
private static State state = new Initial();
public static Value getValue() {
return state.getValue();
}
private static class Initial implements State {
#Override
public synchronized Value getValue() {
if (state instanceof Initial) {
Value value = new Value();
value.x = 1;
value.y = 2;
state = new Initialized(value);
return value;
} else {
return state.getValue();
}
}
}
private static class Initialized implements State {
private final Value value;
private Initialized(Value value) {
this.value = value;
}
#Override
public Value getValue() {
return value;
}
}
private interface State {
Value getValue();
}
public static final class Value {
private int x;
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
}
}
Is this code thread-safe ?
Specifically I am asking about the final field and the guarantees it gives, so the question may be reformulated as is that possible for some thread to get a non-initialized instance of Value ?
UPDATE: removed mention about setters, so that only reads are available after publication
Well, besides the fact that your approach is way too complicated as Bohemian ♦ has pointed out, it could work regarding publication. If two threads access getValue() concurrently, only one thread can enter the synchronized block. The other will either be blocked on the synchronized block or see an instance of Initialized with a correctly initialized value field due to the final field initialization guaranty.
However, it still doesn’t work because the instance of class Value is mutable and your comment // getters and setters indicates that the instance will be mutated after construction. In this case the entire final field initialization guaranty is pointless as the Value class is not thread safe. You might be guarded against seeing the default values for x and y but you will never know what values regarding later-on modifications you will see and the values for (x, y) are not necessarily consistent.
No, this is not thread safe. There is no memory barrier on the read of ValueProvider.state and none at all on Value.
The rule of thumb with Java concurrency is that there needs to be a memory barrier on read and a memory barrier on write.
The only ways to add a memory barrier in Java are:
synchronized
volatile
class initialisation (implicit by the jvm)
atomic
unsafe
For most things Hotspot ignores the final keyword, and prefers to infer it itself. However where final does affect the JMM is to do with class construction and inlining. The reordering rules for final fields are covered in the cookbook that you have already mentioned. It does not mention final classes. The cookbook states:
Loads and Stores of final fields act as "normal" accesses
with respect to locks and volatiles, but impose two additional reordering
1) A store of a final field (inside a constructor and, if the field is a reference, any store that this final can reference, cannot be reordered with a subsequent store
2) The initial load (i.e., the very first encounter by a thread) of a final field cannot be reordered with the initial load of the reference to the object containing the final field.
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
Java Code:
public class IncreaseTest {
public static int value = 0;
public synchronized int increment() {
return value++;
}
}
Is method increment() thread-safe? Do I have to add the modifier keyword volatile as follows:
public static volatile int value = 0;
This code is not thread-safe. The instance method will synchronize on an instance, if you have multiple instances they will not use the same monitor and therefor the updates can interleave.
You either need to remove the static from the value field or add static to the increment() method.
Also, as you have made value public, there is the additional problem that value can be changed or read outside of this method without using synchronisation which could result in reading old values.
So changing your code to the following will make it thread-safe:
public class IncreaseTest {
private int value = 0;
public synchronized int increment() {
return value++;
}
}
You should probably use atomicvars
If you are using this method in two threads then you do need the volatile keyword. Without it, another thread may not get the most up to date value. (C#)
I do not think this is thread safe since the static variable is public and can be accessed by other threads in a non-thread safe manner. In order to be thread safe you must declare the variable as follows:
public static volatile int value;
Now value being volatile, will be accessed in a synchronized block.
Why should a static method in java accept only final or non final variables within its method, but not static?
For example I have the following method:
public static void myfunc(int somethig)
{
int a=10;
final int b=20;
static int c=30; //gives Error why?
}
The question is: why not?
Consider this: what would a static local variable mean?
I suggest that the only sensible meaning would be that this:
public class Foo {
static int bar = 21;
public void foo() {
static int bar = 42; // static local
return bar;
}
}
is equivalent to this:
public class Foo {
static int bar = 21;
private static foo$bar = 42; // equivalent to static local
public void foo() {
return bar;
}
}
In other words, (hypothetical) static locals would be equivalent to regular static attributes with slightly different visibility rules.
The Java language designers probably considered this, and decided that static locals added so little of real value that they were not worth including in the language. (Certainly, that's the way I would have voted.)
In Java (in Object Oriented Programming in general), objects carry state. Methods should share state through objects attributes, not through static local variables.
You can't have static local variable. It doesn't really make sense.
However you can have a static field in your class.
Resources :
JLS - Local Variable Declaration Statements
You can not have a static variable. There is no such thing. You can have a class variable as static instead.
Since every function in java has to be inside a class, you can get the same effect by declaring fields in your class. It's the simplest way, and java language designers are very conservative. They'd never add a feature like that, when there's a more obvious and less complex way to do the same thing.
EDIT: I guess philosophically functions aren't first class in java. They're not supposed to store data. Classes are, and they do.