jni/java: thread safe publishing/sharing of effectively immutable native object - java

1) I have a native java function which passes several params and its implementation is a native C++ constructor to create an object and returns a long which is cast from the pointer to object. This object's constructed members are effectively immutable. The C++ object then can do work based on its constructed state.
2) java code that gets the result of the function call safely publishes the longified version of the pointer somewhere (without mutex) and changes a volatile variable to hopefully publish the memory changes in the native C++ object to other threads
Now another thread reads that volatile variable of 2), and then picks up that published long, and calls another native function that accesses that effectively immutable object in the C++ memory space to do some work.
Question: Is that other thread guaranteed to see the fully constructed native object because of the Java Memory Model guarantees about volatiles and fences? I would bet the answer is yes on some platforms, but I see that different chips work in different ways with using fences, and was wondering about all platforms for which java is available.

A co-author of JCIP answered the question on the JSR mailing list for concurrency.
He says: "JMM [makes no] guarantees extending to anything outside the Java heap - or more specifically it only applies to Java fields", but that "In practice the barriers/fences used today are coarse-grained and will affect all memory equally", so "that in practice this [the volatile publishing attempt described in the question] will work fine (as long as you are using normal process memory)".
Another respondent on the mailing list says: "Some of us have definitely considered it a goal to ensure that Java, C, and C++ synchronization works together as expected, with Java synchronization providing the right visibility guarantees for C or C++ variables, and conversely" but adds that "there is no written guarantee of that [behavior]".

What you pass from java code to native code is copied and passed in the appropriate datatypes for the native code (for example C++ has unsigned int while Java does not, null terminated strings etc).
After that, any threading issues are related to the implementation of the native code.
Essentially it is the same an API. What are the contracts for the API? Does it specify that it can be accessed safely by multiple threads or not?

Java doesn't even know about the existence of the native object you created in your C code, so how can its memory model possibly provide any guarantees about it? All that Java knows about, and can guarantee the behavior of, is the volatile long.

Related

How are the final multi-threading guarantees and the memory model related in Java?

The memory model is defined in 17.4. Memory Model.
The final field multi-threading guarantees are given in 17.5. final Field Semantics.
I don't understand why these are separate sections.
AFAIK both final and the memory model provide some guarantees.
And any real program execution must respect both guarantees.
But it's now clear whether the final guarantees work for the intermediate executions used to validate causality requirements in 17.4.8. Executions and Causality Requirements.
Another unclear moment is that 17.5.1. Semantics of final Fields defines a new "special" happens-before, which differs from the happens-before in the memory model:
This happens-before ordering does not transitively close with other happens-before orderings.
If these are the same happens-before, then the happens-before isn't a partial order anymore (because it isn't transitive).
I don't understand how this doesn't break things.
If these are different happens-before, then it's not clear what the one in 17.5. final Field Semantics does.
The happens-before in 17.4. Memory Model is used to restrict what a read can return:
Informally, a read r is allowed to see the result of a write w if there is no happens-before ordering to prevent that read.
But 17.5. final Field Semantics is a different section.
The special 'final field guarantees' part was a later add-on. Documentation sometimes follows the quirks of history - possibly, had the 'final field guarantee' issue been discovered prior to the first release of the JMM, the documentation would have been structured differently.
In other words, you're asking for 'why is this stuff in a separate chapter' and perhaps the answer is: "Because it was added in a later version of java, and therefore it was written at a completely different time; a new chapter is presumably the simplest way to add some more documentation". We're talking about decades ago at this point, of course.
§17.5 explains its purpose. Quote:
The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.
In other words, in the distant past, you could do this:
Thread A:
Make a new object. The constructor is 'well behaved' 1
Communicate the ref to this new object to another thread. Possibly in an unsafe way.
Thread B:
The receiving thread gets the correct ref (either because you did it safely with synchronization, i.e. happens-before relationship set up properly, or because you did it unsafely, but the JMM does not guarantee that unsafe code fails to work: It may still work).
It calls a method of this object.
Said object witnesses a final-marked field that isn't initialized, because the initialization did occur in thread A, but no happens-before relationship exists, and re-ordering and other shenanigans means that this thread doesn't see it yet.
This is extremely annoying. Part of the point of immutable classes is that you can more or less print out the JMM and set it on fire. You just don't need to care about virtually every tricky rule in it if your system is an amalgamation of immutable types. Except, it didn't actually work out that way prior to the existence of §17.5
The JMM as a general principle is designed to give any JVM implementations as few 'handcuffs' as possible whilst making developing for the JVM as uncomplicated as possible. It's a fine line - for example, had the JMM simply stated: "The JVM is free to re-order whatever it wants at any time, and cache whatever it wants, at any time, for whatever duration it wants", then writing JVMs that run code quickly and according to spec would be 'easier' (JVM impls would be faster), but, writing multithreaded code that actually does what you intended it to becomes borderline impossible. On the flipside, the JMM could also have guaranteed that re-ordering in the JVM is impossible to observe regardless of circumstance or architecture. But then JVMs would be slow as molasses, see Python and its much maligned global interpreter lock.
The JMM tries to be the happy compromise. And §17.5 is written with the same spirit.
It basically says:
You CAN rely on the notion that any well-behaved construction means that final fields will just work out without having to worry about happens-before relationships whatsoever.
However, you CANNOT, at all, rely on HOW the JVM implements the guarantee. In particular, we have defined what you can exactly rely on in terms of Happens-Before, but it's not the same H-B that the rest of the JMM talks about. We guarantee you that well-behaved construction means final fields won't be an issue but that's as far as our guarantee goes: You cannot use this guarantee to then force other guarantees out of the JMM; you can't use this mechanism as a wonky way to establish H-B for other stuff, for example.
The JMM buys room to maneuver for JVM impls. Whether a JVM impl actually uses it, is up to the JVM implementor. In other words, a JVM implementor may well decide to implement §17.5 by using the same locking mechanisms it uses to guarantee the H-B stuff in §17.4, and thus effectively you can apply properties like 'H-B relationships are transitive'. The point of the JMM is partly to allow JVM impls to take some pretty drastically different approaches to how the guarantees it dictates are in fact guaranteed. That's because JVMs have to be written so that they can run code about as fast as native code could on a wide variety of hardware, whilst still being a target platform that isn't impossible to develop for.
Quite the tightrope walk. This is the primary underlying explanation for the JMM can be obtuse and bizarre at times.
[1] A 'well behaved' constructor:
Does not pass its own reference (this) to any code outside of its own class during construction.
Does not invoke any of its own instance methods that then read its own fields (or, especially problematic, which can be overridden by subclasses, whose implementation uses its own fields). Basically: Calling any non-final method is an instant "You are not well behaved" violation.
Does not send any object refs of things I wishes to store in fields to code in other classes during construction. Even if it has already assigned it to the final field before doing so.

Mutable Object safe publication with one only one thread writing

Let non-threadsafe, mutable object X be constructed in thread A. A passes X, post construction, to thread B. B mutates X and A never accesses X again.
Will the state of X always be properly visible to B?
Is X effectively thread confined?
My reading of Java Concurrency in Practice seems to indicate that X is not properly published but I cannot cause any problems for thread B in test rigs that run millions of replications. I suspect this is just dumb luck.
For background, X represents a multitude of complex classes over which I have no control that are authored by modelers who have only a basic knowledge of Java. It is strongly preferred that X has no synchronized blocks or other concurrency mechanisms or requirements.
I am currently solving this problem by having thread A pass a thread-safe factory for X that B invokes, thus making X thread confined.
Publication only safe for final fields
The Java Memory Model doesn't guarantee that the object X will be completely published (fully constructed) to thread A.
To ensure that, you would need to make it immutable (all member fields final) or synchronize.
Quoting JSR-133:
The semantics of final fields have been strengthened to allow for thread-safe immutatability
without explicit synchronization. This may require steps such as store-store barriers at the
end of constructors in which final fields are set.
Only thing you need to avoid is leaking fields out of the class before the constructor finishes.
Testing
jcstress has in fact a sample project to demonstrate consequences of racing during publication: JMMSample_06_Finals.java
Note that some efforts had to be done to replicate the problem, like using many fields.
The implementation of the JMM depends naturally on the particular JRE that you are using and also the effects of memory barriers being used depend on the hardware being used.
On my hardware using Oracle JDK 8 I'm not able to reproduce unsafe publication using the sample with jcstress.
Synchronizing
There is a "happens-before" relationship between all synchronization actions. This is known as the synchronization order. Basically when you use any synchronization mechanism, you have the guarantee that actions before it will be visible after it.
As concluded in the Java Language Specification:
If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent
In practice
In practice it's very hard to run into problems due to actions taken in a constructor not being visible by threads using the object.
A primary reason is the usage of synchronization mechanisms. You can check some of the actions that will ensure the happens-before relationship in the javadoc: Memory Visibility
Also as I mentioned with the jcstress sample, JRE nowadays seems to be very good in ensuring consistent results even when it doesn't need to according to the language specification.

Risks of volatile-mutable fields in single-threaded contexts?

Is it safe to use the :volatile-mutable qualifier with deftype in a single-threaded program? This is a follow up to this question, this one, and this one. (It's a Clojure question, but I added the "Java" tag because Java programmers are likely to have insights about it, too.)
I've found that I can get a significant performance boost in a program I'm working on by using :volatile-mutable fields in a deftype rather than atoms, but I'm worried because the docstring for deftype says:
Note well that mutable fields are extremely difficult to use
correctly, and are present only to facilitate the building of higher
level constructs, such as Clojure's reference types, in Clojure
itself. They are for experts only - if the semantics and implications
of :volatile-mutable or :unsynchronized-mutable are not immediately
apparent to you, you should not be using them.
In fact, the semantics and implications of :volatile-mutable are not immediately apparent to me.
However, chapter 6 of Clojure Programming, by Emerick, Carper, and Grand says:
"Volatile" here has the same meaning as the volatile field modifier in
Java: reads and writes are atomic and must be executed in
program order; i.e., they cannot be reordered by the JIT compiler or
by the CPU. Volatiles are thus unsurprising and thread-safe — but
uncoordinated and still entirely open to race conditions.
This seems to imply that as long as accesses to a single volatile-mutable deftype field all take place within a single thread, there is nothing to special to worry about. (Nothing special, in that I still have to be careful about how I handle state if I might be using lazy sequences.) So if nothing introduces parallelism into my Clojure program, there should be no special danger to using deftype with :volatile-mutable.
Is that correct? What dangers am I not understanding?
That's correct, it's safe. You just have to be sure that your context is really single-threaded. Sometimes it's not that easy to guarantee that.
There's no risk in terms of thread-safety or atomicity when using a volatile mutable (or just mutable) field in a single-threaded context, because there's only one thread so there's no chance of two threads writing a new value to the field at the same time, or one thread writing a new value based on outdated values.
As others have pointed out in the comments you might want to simply use an :unsynchronized-mutable field to avoid the cost introduced by volatile. That cost comes from the fact that every write must be committed to main memory instead of thread local memory. See this answer for more info about this.
At the same time, you gain nothing by using volatile in a single-threaded context because there's no chance of having one thread writing a new value that will not be "seen" by other thread reading the same field.
That's what a volatile is intended for, but it's irrelevant in a single-thread context.
Also note that clojure 1.7 introduced volatile! intended to provide a "volatile box for managing state" as a faster alternative to
atom, with a similar interface but without it's compare and swap semantics. The only difference when using it is that you call vswap! and vreset! instead of swap! and reset!. I would use that instead of
deftype with ^:volatile-mutable if I need a volatile.

Plain C++ objects in code accessed by JNI

My Android application has a native C++ layer and a Java layer. The Java layer accesses the native layer via JNI calls.
Can the C++ layer safely create C++ objects for its own internal use, and store them in C++ member variables? I'm talking about C++ objects that don't need to be accessed by Java code in any way, i.e. they are managed and deleted completely in the C++ layer. In other words, the same object (via a member variable) is accessed throughout multiple JNI calls, but only the C++ layer needs to access it.
I need confirmation in this matter, because I know that there are special JNI methods for handling objects (relevant terms: local reference, global reference, etc.). If I'm correct, these apply only for objects that are visible by (or created for) Java code as well.
Therefore, I suppose that native-only C++ objects can be created and deleted in the usual ways (such as new and delete), and Java doesn't need to know anything about them. No special interoperability considerations are necessary, as long as the objects and any references to them reside exclusively in the C++ layer. Is this correct? Can I define C++ classes and methods in this layer in the same way as if it was a usual C++ application without any JNI/Java interoperability? To be general, is it allowed to instantiate and store plain C++ objects, i.e. objects that are out of the authority of Dalvik/JVM?
Indeed, the JNI methods for handling objects are for the Java objects.
You can create C/C++ objects in any way you can imagine (malloc/new), but: how will you preserve them across JNI calls? (If you need that, of course.) Two options:
Convert the pointer into an integer and pass that integer to Java. (You will have to care about pointers stored in garbage-collected Java objects, you see, the integers do not imply freeing the native memory.)
Have some C/C++ data structure with all the necessary references.
Thread-safety deserves separate consideration; if you try to store pointers in thread-local variables, you probably will never debug the code (you see, there's a life cycle mismatch).
Good results may be achieved with static global variables accessed from just one thread.
And keep in mind that Android may kill and restart your application's process, thus destroying everything stored in static variables, as well as your native data structures.

Why most of the java.lang.reflect.Array class methods are 'native'

I have gone through What code and how does java.lang.reflect.Array create a new array at runtime?,. I understand that they are implemented in native language ('C'), But my question is why almost all methods java.lang.reflect.Array class methods are native .
My guess and understanding is that
To improve performance ? or to allocate continuous memory for arrays by JVM ?
Is my understanding correct about native methods in Array class or Do i miss anything ?
The reflect.Array.newInstance method uses native code because it must use native code. This has nothing inherently to do with performance but is a result of the fact that the Java language cannot express this operation.
To show that it's a language limitation and not strictly related to performance, here is some valid code which creates a new array without directly invoking any native method.
Object x = new String[0];
However, newInstance takes an arbitrary value of Class<?> and then creates the corresponding array with the represented type. However, this construct is not possible in plain Java and it cannot be expressed by the type-system or corresponding normal "new array" syntax.
// This production is NOT VALID in Java, as T is not a type
// (T is variable that evaluates to an object representing a type)
Class<?> T = String.class;
Object x = new T[0];
// -> error: cannot find symbol T
Because such a production is not allowed, a native method (which has access to the JVM internals) is used to create the new array instance of the corresponding type.
While the above argues for the case of newInstance needing to be native, I believe many of the other reflect.Array methods (which are get/set methods) could be handled in plain Java with the use of specialized casting; in these cases the argument for performance holds sway.
However, most code does not use the Array reflection (this includes "multi-valued data structures" such as ArrayList), but simply uses normal Java array access which is directly translated to the appropriate Java bytecode without going through reflect.Array or the native methods it uses.
Conclusion:
Java already provides fast array access through the JVM's execution of the bytecode. HotSpot, the "official" JVM, is written in C++ which is "native" code - but this execution of array-related bytecode is independent of reflect.Array and the use native methods.
newInstance uses a native method because it must use a native method or otherwise dynamically generate and execute bytecode.
Other reflect.Array methods that could be expressed in Java are native methods for a combination of performance, dispatch simplicity, and "why not" - it's just as easy to add a second or third native method.
Arrays are at the heart of all multi-valued data structures. Arrays require using segments of memory on the host machine, which means accessing memory in a safe, and machine specific manner - that requires calls to the underlying operating system.
Such calls are native because to perform them you must move out of java and into the host environment to complete them. At some point every operation must be handed over to the host machine to actually implement it using the local OS and hardware.

Categories