This is the third part of the Concurrency series. For your convenience you can find other parts in the table of contents in Part 1 – Mutex performance in .NET
Last time we saw file lock in Java which we can use on every platform. However, if we stick to Windows only, we can use WinAPI mutexes through JNI. Let’s go.
Code
First, Java application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class JavaMutex { static { System.out.println(System.getProperty("java.library.path")); System.loadLibrary("MutexJava"); } private native long createMutex(); private native void acquireMutex(long mutex); private native void releaseMutex(long mutex); private void test(){ long mutex = createMutex(); while(true){ long startTime = System.currentTimeMillis(); for(int i=0;i<100000;++i){ acquireMutex(mutex); releaseMutex(mutex); } long estimatedTime = System.currentTimeMillis() - startTime; System.out.println(estimatedTime); } } public static void main(String[] args){ new JavaMutex().test(); } } |
We define three methods to use Mutex. Observe that we use long instead of HANDLE. HANDLE is a void*
which we can consider a number in our case.
Next, we generate the JNI header:
1 |
javac -h . JavaMutex .java |
and here is the result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JavaMutex */ #ifndef _Included_JavaMutex #define _Included_JavaMutex #ifdef __cplusplus extern "C" { #endif /* * Class: JavaMutex * Method: createMutex * Signature: ()J */ JNIEXPORT jlong JNICALL Java_JavaMutex_createMutex (JNIEnv *, jobject); /* * Class: JavaMutex * Method: acquireMutex * Signature: (J)V */ JNIEXPORT void JNICALL Java_JavaMutex_acquireMutex (JNIEnv *, jobject, jlong); /* * Class: JavaMutex * Method: releaseMutex * Signature: (J)V */ JNIEXPORT void JNICALL Java_JavaMutex_releaseMutex (JNIEnv *, jobject, jlong); #ifdef __cplusplus } #endif #endif |
Now we implement the methods in C++ with Visual Studio 2017:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <windows.h> JNIEXPORT jlong JNICALL Java_JavaMutex_createMutex (JNIEnv *, jobject) { HANDLE mutex = CreateMutex(NULL, FALSE, L"mutex_java"); return (jlong)mutex; } JNIEXPORT void JNICALL Java_JavaMutex_acquireMutex (JNIEnv *, jobject, jlong mutex) { WaitForSingleObject((HANDLE)mutex, INFINITE); } JNIEXPORT void JNICALL Java_JavaMutex_releaseMutex (JNIEnv *, jobject, jlong mutex) { ReleaseMutex((HANDLE)mutex); } |
Compile, run with -Djava.library.path="..."
and test.
Results
As we can see, the results are quite nice, even better than .NET. Next time we will see if we can improve C# code.