JNI stands for Java Native Interface. It is a framework for communication between Java and Native code. Basically a program in Java can call a native program written in C++ and the other way around. I would say it's not very common in general software development but it becomes important when dealing with performance critical applications like games.
Now why would we make a game in Java at first place? The answer is Android. Every Android app must be done in Java, however the Java app can call a native library that will do all the heavy work.
Using of the JNI framework is somewhat clumsy but if you follow the documentation you can create a simple communication layer passing basic types to Java and back. The problems will come when you start dealing with multithreaded environment.
Imagine a scenario when you have a low level networking library written in Java and a multithreaded native application written in C++. The communication works well if all JNI calls are run from the main native thread. But whenever you try to call JNI from the worker thread the communication will fail.
According to documentation the JNI can be attached to only one thread. In case of another thread, a new JNI interface must be created by attaching secondary thread to Java Virtual Machine. Once attached, the JNI will work like a regular Java thread. You can imagine that attaching threads to JVM is quite expensive operation so it's advised to cache the JNI pointer inside the native thread.
To be continued...