получить доступ к синхронизированному методу Java из собственного кода - PullRequest
9 голосов
/ 28 сентября 2011

У меня есть класс Java, который имеет некоторые (частные статические) синхронизированные методы, которые я также хочу вызывать из нативного кода. с некоторым примером кода становится более понятным, что я имею в виду

public class SomeClass {
   private static synchronized void method() {
     //do something that needs synchronization
   }
}

и связанный нативный код (C ++)

void someFunction(JNIEnv * env) {
   jclass someClass = env->findClass("SomeClass");
   jmethodID methodId = env->GetStaticMethodID(jclass, "method", "()V");
   env->MonitorEnter(jclass); // <--- IS THIS NEEDED/ALLOWED
   env->CallStaticVoidMethod(jclass, methodId);
   env->MonitorExit(jclass); // <--- IS THIS NEEDED/ALLOWED
}

Поэтому меня интересует, нужно ли мне вызывать MonitorEnter / MonitorExit или если синхронизация метода уже выполняется атрибутом synchronized в SomeClass.method (). Я не очень заинтересован в переписывании кода. Я могу придумать несколько решений, чтобы обойти это, но мне интересно, каково это поведение, учитывая синхронизированный метод, который вызывается из собственного кода.

Ответы [ 3 ]

6 голосов
/ 28 сентября 2011

Раздел 8.4.3.6 синхронизированные методы Спецификации языка Java говорит, что объявление синхронизированного метода имеет тот же эффект, что и добавление синхронизированного блока в метод.

3 голосов
/ 28 сентября 2011

Нет, явные MonitorEnter / MonitorExit не нужны.Согласно Руководству по JNI ,

... предпочтительно выражать конструкции синхронизации на языке программирования Java.Если, например, статическому собственному методу требуется ввести монитор, связанный с его определяющим классом, вы должны определить статический синхронизированный собственный метод, а не выполнять синхронизацию монитора уровня JNI в собственном коде.

Даже если ваш случай вызова метода Java из нативного кода (а не наоборот) прямо не обсуждается в спецификации, обратное также не указано, поэтому я бы предположил , что он работает аналогично.

0 голосов
/ 28 сентября 2011

Если у вас есть SomeClass, вы можете просто сделать

public class SomeClass {
private static synchronized void method() {
     //do something that needs synchronization
   }

private static void synchronizedMethod() {
     method();
   }
}

и просто позвоните synchronizedMethod() из C ++.

...