0

I am calling for e.g. getServer() method implemented in C++ library using JNA which takes input parameter and connects to server and return the server object. I am calling above native method using different Java threads. And this native method uses some global variables where native method is implemented.

I have declared native method in Native.h file as extern "C" and implementing native method in Native.cpp file. This method is standalone method i.e. not part of any class or structure.

So my query here is, if there are some global variables present in Native.cpp, are their value being changed from different Java threads which calls same native method?

Prashant
  • 11
  • 4
  • If your method is executing getters and setters method for global variables then yes the value change. – Lokesh Pandey Oct 11 '17 at 08:54
  • I'm tempted to mark this is a duplicate of [Concurrency issue while calling a native library via JNA](https://stackoverflow.com/questions/6983007/concurrency-issue-while-calling-a-native-library-via-jna) as it answers your question indirectly and provides a workaround. Agreed that this answers your question? – Erwin Bolwidt Oct 11 '17 at 09:29
  • @ErwinBolwidt :- the mentioned link explaining about how to synchronize the call from Java to native. But in my case, I want to know about global variables which are present in native file. – Prashant Oct 11 '17 at 09:45
  • It should (I think) confirm for you that JNA doesn't magically transform your global variable to something else, and that it doesn't synchronize all native calls - so that answer is: yes, of course the values are being changed from different java threads that call native methods that change the same global variables. – Erwin Bolwidt Oct 11 '17 at 09:50

1 Answers1

0

Are their value being changed from different Java threads which calls same native method?

Sure, the global variables will be shared by all virtual machine then by threads as well, let's write a very simple example to proof that:

counter.c

#include<stdio.h>

int counter = 0;
int incrementAndGet(){
    counter++;
    return counter;
}

Calling it in java using JNA

final ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 20; i++) {
    executorService.submit(() -> {
        try {
            TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 1000));
        } catch (InterruptedException e) {}
        System.out.printf("thread=%s, counter=%d%n", Thread.currentThread().getName(), CounterLib.INSTANCE.incrementAndGet());
    });
}
executorService.awaitTermination(10, TimeUnit.SECONDS);
executorService.shutdown();

output

thread=pool-1-thread-2, counter=1
thread=pool-1-thread-4, counter=2
thread=pool-1-thread-1, counter=3
thread=pool-1-thread-5, counter=4
thread=pool-1-thread-2, counter=5
thread=pool-1-thread-3, counter=6
thread=pool-1-thread-2, counter=7
thread=pool-1-thread-4, counter=8
thread=pool-1-thread-1, counter=9
thread=pool-1-thread-2, counter=10
thread=pool-1-thread-5, counter=11
thread=pool-1-thread-3, counter=12
thread=pool-1-thread-5, counter=13
....

You also must worry about concurrency at this global variables, or at java or at c, in the two is not necessary, then if you are just reading values from the global variables then you must not worry about concurrency.

deFreitas
  • 4,196
  • 2
  • 33
  • 43