| Implementing Native Methods

## Native Methods and Thread Synchronization

> Sometimes, a native method contains a critical section of code--a section of code that accesses or modifies a condition variable. Like other critical sections or methods in Java, these native methods have to be synchronized with other methods or code blocks that access the same variable. Synchronization ensures that code running in different threads accesses the condition variable in safety and that the condition variable is in some globally consistent state. Threads of Control covers programming with threads. In particular, the page Multithreaded Programs covers issues related to writing programs that contain multiple threads, including how to synchronize them. You should be familiar with the concepts in that section before proceeding here.

> Three utility functions declared in `monitor.h` allow native methods to interact with Java's monitor mechanism, so that native methods can be thread-safe like regular Java methods. Those functions are:

> `monitorWait()`
>   Blocks until notification is made on the specified monitor. The `monitorWait()` function is equivalent to Object's `wait()` method.
> `monitorNotify()`
>   Notifies one waiting thread that there is a change of condition on the specified monitor. The `monitorNotify()` function is equivalent to Object's `notify()` method.
> `monitorNotifyAll()`
>   Notifies all waiting threads that there is a change of condition on the specified monitor. The `monitorNotifyAll()` function is equivalent to Object's `notifyAll()` method.
> Let's look at an example program that uses these functions to synchronize the execution of two native methods. This example program is a modified version of the Producer/Consumer example found in Synchronizing Threads.

> The example program is comprised of these four classes:

> Producer
>   A thread that produces integer values and puts them in a "cubby hole".
> Consumer
>   A thread that consumes the values placed in the cubby hole by the producer.
> ProducerConsumerTest
>   The main program that starts the producer and consumer threads.
> CubbyHole
>   The object where the producer puts its values and the consumer gets them. In the previous, Java-only implementation of this example, the `put()` and `get()` methods in this class were synchronized. The program has been modified so that `put()` and `get()` are now native methods and use the `monitorXXX()` functions to synchronize the producer and consumer threads. This is the only class that needed to be modified.
> Let's look at the new CubbyHole class. The changes made to the CubbyHole class are in bold.

> >     class CubbyHole {
> >         private int seq;         // this is the condition variable.
> >         private boolean available = false;

> >         public synchronized native int get();
> >         public synchronized native void put(int value);

> >         static {
> >             try {
> >                 System.loadLibrary("threadex");
> >             } catch (UnsatisfiedLinkError e) {
> >                 System.err.println("can't find your library");
> >                 System.exit(-1);
> >             }
> >         }
> >     }

> Here's the original version of the CubbyHole class for comparison.

> The first change is that the `get()` and `put()` methods are now declared `native` (as well as synchronized) and their implementations have been removed. They are now implemented in C in the file `CubbyHoleImpl.c`.

> The second change is the addition of a static initializer block. This block of code loads the dynamic library `threadex` that contains the implementations for the `get()` and `put()` methods.

> Now, let's look at the new implementations for `get()` and `put()`.

> >     long CubbyHole_get(struct HCubbyHole *this) {
> >         while (unhand(this)->available == 0) {
> >             monitorWait(obj_monitor(this));
> >         }
> >         unhand(this)->available = 0;
> >         monitorNotify(obj_monitor(this));
> >         return unhand(this)->seq;
> >     }

> >     void CubbyHole_put(struct HCubbyHole *this, long value) {
> >         while (unhand(this)->available > 0) {
> >             monitorWait(obj_monitor(this));
> >         }
> >         unhand(this)->seq = value;
> >         unhand(this)->available = 1;
> >         monitorNotify(obj_monitor(this));
> >     }

> The logical flow of these methods is identical to the Java implementation of these methods. Note the use of `monitorWait()` and `monitorNotify()` is identical to the use of the `wait()` and `notify()` methods in the Java version.

| Implementing Native Methods