Read Indirect state Vs. Read Direct state of a variable in java - java

In following code compilation fails for static variable j inside the static block, as mentioned in comment.
However, It is working fine inside the method m1()
class StaticBlock {
static {
m1();
//compilation fails because variable are in read indirect state
System.out.println(j);
}
static void m1() {
System.out.println(j);
}
static int j = 10;
I know root cause of compilation failure - variable j is in Read Indirect State.
My question- Why is this behavior, we can also print 0 inside static block as we are doing in m1().
What made API developers to have this discrepancy

Why is this behavior, we can also print 0 inside static block as we
are doing in m1().
What made API developers to have this discrepancy
There are competing priorities revolving around simple specifications for the order of events during class initialization, consistency of constant (i.e. final) class fields, programmer expectations, and ease of implementation.
The values of constant fields provides a good starting point. Java would like to avoid the default values of such fields being observable, and especially to avoid their default values being used in the initialization of other class variables. Therefore, these are initialized first, before static initializer blocks or the initializers of other class variables. They are initialized in the order they appear in the source code, which is a rule that is easy for both humans and compilers to understand. But that affords the possibility that the initializer of one class variable sees the default value of another, yielding surprising, unwanted results. Java therefore specifies that that case must be detected and rejected at compile time.
Static initializer blocks and the initializers of other class variables are executed afterward, in the order they appear in the source code. The case for the constraint you're asking about is not as strong here, but it's reasonable to choose consistency by applying the same rule here as is applied to class constants. Combined, the effect is to have easy to understand and predict initialization order that is also mostly consistent with a model of class variables' initializers being evaluated and assigned before static initializer blocks are evaluated.
But then come static methods. It is highly desirable for static methods to be available for use during initialization, but they are also usable after initialization is complete, when none of the initialization-order considerations are relevant. It is therefore unfeasible to restrict static methods' access to variables based on order of appearance in source code. Conceivably, the VM could instead be required to keep track of class variables' individual initialization state, either by control-flow analysis at compile time or by some form of runtime monitoring, but rather than require such complexities, Java opts for simplicity, allowing people who insist on making a mess (by observing default values of class variables) to do so.
I emphasize, finally, that so-called "Read Indirect Write Only state" is part of a third-party model of how this all works. Java itself has no such concept -- such a thing is exactly what it rejects in favor of simplicity when it comes to requirements on static methods' use of class variables.

Related

Can Java lambda expressions be guaranteed not to hold a reference to `this`?

If a lambda expression does not refer to any methods or fields of the surrounding instance, does the language guarantee that it doesn't hold a reference to this?
In particular, I want to use lambda expressions to implement java.lang.ref.Cleaner actions. For example:
import static some.Global.cleaner;
public class HoldsSomeResource {
private final Resource res;
private final Cleanable cleanup;
public HoldsSomeResource(Resource res) {
this.res = res;
cleanup = cleaner.register(this, () -> res.discard());
}
public void discard() {
cleanup.clean();
}
}
Clearly, it would be bad if the lambda expression implementing the cleanup action were to hold a reference to this, since it would then never become unreachable. It seems to work when I test it right now, but I can't find the obvious reference in the JLS that it is guaranteed to be safe, so I'm slightly worried that I might run into problems in alternative and/or future Java implementations.
The specification does indeed not mention this behavior, but there is a statement in this document from Brian Goetz:
References to this — including implicit references through unqualified field references or method invocations — are, essentially, references to a final local variable. Lambda bodies that contain such references capture the appropriate instance of this. In other cases, no reference to this is retained by the object.
While this isn’t the official specification, Brian Goetz is the most authoritative person we can have to make such a statement.
This behavior of lambda expressions is as intentional as it can be. The cited text continues with
This has a beneficial implication for memory management: while inner class instances always hold a strong reference to their enclosing instance, lambdas that do not capture members from the enclosing instance do not hold a reference to it. This characteristic of inner class instances can often be a source of memory leaks.
Note that this other behavior, inner class instances always holding an implicit reference to the outer this instance, also does not appear anywhere in the specification. So when even this behavior, causing more harm than good if ever being intentional, is taken for granted despite not appearing in the specification, we can be sure that the intentionally implemented behavior to overcome this issue will never be changed.
But if you’re still not convinced, you may follow the pattern shown in this answer or that answer of delegating to a static method to perform the Cleaner registration. This has the benefit of also preventing accidental use of members while still being simpler than the documentation’s suggested use of a nested static class.
I think you're safe. It's not an aspect of the JIT or a garbage collector implementation (stuff from "java.exe") ; this is done directly by the compiler ("javac.exe"). It's not going to 'backslide' and inject useless and potentially pricey variables. It also means you are not dependent on a JVM's behaviour: you're merely dependent on a compiler's behaviour. For starters, there aren't all that many (ecj and javac that's pretty much it - all others you might be thinking of are forks of those, or are wrappers around those), and I'm pretty sure both ecj and javac don't capture the this now and presumably never will in the future.
A bigger issue is that javac certainly won't complain if you 'accidentally' do happen to capture anything that requires the this ref; that will lead to the this ref getting silently captured and ruining your cleanup library rather thoroughly. It feels like you've designed a library here where it's rather all too easy to shoot yourself in the foot.
I'm not quite sure what you can do to fix this. Possibly you can lean into it and use ASM or bytebuddy or similar to tear the class open1 and doublecheck that the this ref is not seeing capture. It's probably not worth the potentially sizable time it'd take to chase down all the refs to ensure that this isn't captured in a roundabout fashion (where the lambda captures variable y, and y has a field of type Bar pointing at some instance and that instance has a field whose value is a ref back to the original this, thus, preventing collection), but checking for direct capture is potentially interesting. Possibly even only in an assert statement so any testcase that does it will result in an AssertionError thrown, failing the test, letting you know this error was made.
[1] You can get the bytes of any class with String.class.getResourceAsStream("String.class") - you can read that InputStream and feed it into ASM / bytebuddy / etc. The costs of running a class through such a loop are considerable, of course.

Is there a pthread_once equivalent in Java?

In C/C++ world, it is very easy make a routine executed just once by using pthread_once. In Java, I generally use static atomic variables to do the explicit check if the routine was run already. But that looks ugly and hence wondering if there is something like pthrea_once in Java.
Since you refer to “static atomic variables” you seem to talk about static resources which do not need special actions if you initialize them within the class initializer itself:
class Foo {
static ResourceType X = createResource();
}
Here, createResource() will be executed exactly once in a thread-safe manner on the first use of Foo, e.g. when Foo.X is accessed the first time. Threads accessing X while the class initialization is in progress are forced to wait, but subsequent access will be performed without any synchronization overhead. Typically, but not necessarily, the variable will be declared final as well.
If you have multiple resources whose creation should be deferred independently, the owner class might use inner classes, each of them holding one resource.
If your question is about an action which should be executed exactly once without returning a value, the static initialization can be used as well. You only have to add a member you can access to trigger the class initialization, e.g.:
class Foo {
static { performAction(); }
static void performActionOnce() {}
}
Here, calling Foo.performActionOnce() will cause performAction() to be executed the first time while all other subsequent invocations do nothing. You can also rely on that on returning from performActionOnce() the action within performAction() has been completed, even when there is contention on the first invocation.
This is different from any atomic variable approach as atomic variables do not provide a sufficient waiting capability for the case that the first invocation is contended. If you combine the atomic variable with a waiting queue, you end up what Lock (or any other AQS based concurrency tool) provides. For instance variables where the static initialization does not work, there is no simple workaround (besides thinking about whether initialization really has to be lazy).

what are the differences in these two ways to initialize a static variable?

What are the differences between the following two examples, if used in an Android applications?
Example-1
public class ExampleClassOne {
public static int x = 9;
}
Example-2
public class ExampleClassTwo{
public static int x;
static{
x = 9;
}
}
For this example there is no difference. The two forms do exactly the same thing. (Indeed, I suspect that the bytecodes produced will be virtually identical.)
There are cases where there is a difference. Or to be more precise, there is a difference in what you can express. A couple that spring to mind are:
A static initializer block can deal with exceptions (especially checked ones) but a initializer expression can't.
A static initializer block can initialize the static to the result of an arbitrarily complicated sequence of statements, but an initializer expression is limited to what you can compute in a single expression.
Having said that, I would recommend that you use the simpler initializer expression form wherever possible. Without doubt, it is more readable.
As per the Oracle tutorial:
public static int x = 9;
This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.
What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.
But in your case , with your code , it makes no difference.
they both are same and would be called and initialized on class creation/initiation.
there are no such differences.
Usually the static block is used for more complex initialization, for instance if you have a List and want to populate it.
Edit (rolled back ;) ) in your case initialization is equivalent though.

Setter methods for final fields

Using reflection and also from the src.zip available in the installed JDK by the installer purveyed by http://docs.oracle.com, I found the following fields of java.lang.System,
in, out & err are declared as final, but they have respective (public) setter methods which in turn invoke their respective native couter-part.
For example, I could successfully re-direct console output to a file.
We can set final variables exactly once we have initialized it in the Java code.
My question is : is this rule of final not applicable to the native code?
My question is : is this rule of final not applicable to the native code?
Native code can break the rules on final. It can also break the access rules and basic type safety, and various other things.
The point about final fields not actually being immutable is actually recognized in the JLS: see JLS 17.5.3. The gist of this is that if you do change a final (via reflection for example), certain guarantees no longer hold. And changing the value of a final that represents a compile time constant is liable to have no effect at all.
But as #ignis points out, System.in/out/err get special mention in the JLS as being "write-protected" (JLS 17.5.4) rather than having the normal final semantics. Basically, this means that the final guarantees do hold even if the variables are changed.
why have the variables to be final when there will be a setter anyways?
In this particular case it is 1) to prevent System.in/out/err from being clobbered by an accidental assignment, and 2) so that changes can be controlled by the SecurityManager.
final makes Java Compiler ensure that no code tries to change the field except initialization. In java.lang.System it is different
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
private static native void setOut0(PrintStream out);
From the point of view of javac there is no violation.
in the source code, they are not reassigning for example out variable in the setOut() method
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
they send the passed stream to native code, and that code is responsible to set that stream for current use. So final variable is not being re-set and this variable is not used in native code, whatever stream it passes to native code , it uses that

Are there inline functions in java?

Is there a concept of inline functions in java, or its replaced something else? If there is, how is it used? I've heard that public, static and final methods are the inline functions. Can we create our own inline function?
In Java, the optimizations are usually done at the JVM level. At runtime, the JVM perform some "complicated" analysis to determine which methods to inline. It can be aggressive in inlining, and the Hotspot JVM actually can inline non-final methods.
The java compilers almost never inline any method call (the JVM does all of that at runtime). They do inline compile time constants (e.g. final static primitive values). But not methods.
For more resources:
Article: The Java HotSpot Performance Engine: Method Inlining Example
Wiki: Inlining in OpenJDK, not fully populated but contains links to useful discussions.
No, there is no inline function in java. Yes, you can use a public static method anywhere in the code when placed in a public class. The java compiler may do inline expansion on a static or final method, but that is not guaranteed.
Typically such code optimizations are done by the compiler in combination with the JVM/JIT/HotSpot for code segments used very often. Also other optimization concepts like register declaration of parameters are not known in java.
Optimizations cannot be forced by declaration in java, but done by compiler and JIT. In many other languages these declarations are often only compiler hints (you can declare more register parameters than the processor has, the rest is ignored).
Declaring java methods static, final or private are also hints for the compiler. You should use it, but no garantees. Java performance is dynamic, not static. First call to a system is always slow because of class loading. Next calls are faster, but depending on memory and runtime the most common calls are optimized withinthe running system, so a server may become faster during runtime!
Java does not provide a way to manually suggest that a method should be inlined. As #notnoop says in the comments, the inlining is typically done by the JVM at execution time.
What you said above is correct. Sometimes final methods are created as inline, but there is no other way to explicitly create an inline function in java.
Well, there are methods could be called "inline" methods in java, but depending on the jvm. After compiling, if the method's machine code is less than 35 byte, it will be transferred to a inline method right away, if the method's machine code is less than 325 byte, it could be transferred into a inline method, depending on the jvm.
Real life example:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Then in other classes, I can exit if the code has expired. If I reference the EXPIRED_ON variable from another class, the constant is inline to the byte code, making it very hard to track down all places in the code that checks the expiry date. However, if the other classes invoke the isExpired() method, the actual method is called, meaning a hacker could replace the isExpired method with another which always returns false.
I agree it would be very nice to force a compiler to inline the static final method to all classes which reference it. In that case, you need not even include the Control class, as it would not be needed at runtime.
From my research, this cannot be done. Perhaps some Obfuscator tools can do this, or, you could modify your build process to edit sources before compile.
As for proving if the method from the control class is placed inline to another class during compile, try running the other class without the Control class in the classpath.
so, it seems there arent, but you can use this workaround using guava or an equivalent Function class implementation, because that class is extremely simple, ex.:
assert false : new com.google.common.base.Function<Void,String>(){
#Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
yes, this is dead code just to exemplify how to create a complex code block (within {}) to do something so specific that shouldnt bother us on creating any method for it, AKA inline!
Java9 has an "Ahead of time" compiler that does several optimizations at compile-time, rather than runtime, which can be seen as inlining.

Categories

Resources