Sun Microsystems 2 Wireless Office Headset User Manual


 
14 Multitasking Guide May 2007
CODE EXAMPLE 2-6 Migrating the Initialization Variable to Native Code (Doesn’t Work)
// Microwave.java
static native boolean getInitState();
static native void setInitState(boolean init);
public static synchronized void lock()
throws InterruptedException {
...
if (!getInitState()) {
init();
setInitState(true);
}
}
Unfortunately, the code in CODE EXAMPLE 2-6 does not work. The reason is that
threads from different tasks can be switched at any time. Suppose that a thread in
task A calls getInitState(), which returns false. The thread decides that the
microwave library needs to be initialized, and it starts to execute the code in the if
block. Now suppose the system switches to run a thread in task B that is also about
to run this code. Task B’s thread also calls getInitState(), which also returns
false, and so this thread also decides to execute the code in the if block. This
results in two calls to the native mw_init() function, which is an error.
From the Java programming language point of view, the tasks are completely
isolated from each other, and therefore threads from different tasks cannot interact.
This means that there is no Java programming language construct that can provide
mutual exclusion between threads that are in different tasks. Therefore, some other
kind of mechanism at the native method level is necessary, because native methods
operate outside the constraints of the Java programming language.
Instead of the flag test and set logic being in Java code, it must also be migrated to
native code, along with the flag itself. In this case, the Java code can call init()
every time and it can rely on the logic in native code to ensure that the mw_init()
function is called only once, as shown in
CODE EXAMPLE 2-7.
CODE EXAMPLE 2-7 Migrating Initialization to Native Code
/* microwave.c */
static int initialized = 0;
KNIEXPORT KNI_RETURNTYPE_VOID
Java_javax_microwave_oven_Microwave_init(void)