2011-09-28 9 views
9

私はネイティブコードからも呼び出すいくつかの(プライベートな静的な)同期メソッドを持つjavaクラスを持っています。いくつかのサンプルコードで、それは私が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場合、またはを呼び出す必要がある場合でありますメソッドの同期は、SomeClass.method()のsynchronized属性によって既に強制されています。 私はコードを書き直すのにあまり興味がありません。これを回避するにはいくつかの解決策が考えられますが、ネイティブコードから呼び出される同期メソッドがあれば、その動作に興味があります。

答えて

6

Java言語仕様のセクション8.4.3.6 synchronized Methodsでは、メソッドの同期化を宣言すると、メソッド内で同期化されたブロックを追加するのと同じ効果が得られます。

+0

ありがとうございます!これらが同じ効果を持つように指定されているとすれば、私はそれらが同じバイトコードを生成すると仮定します。したがって、MonitorEnter/MonitorExitはここでは不要です。 –

0

あなたがSomeClassを所有している場合、あなただけの

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

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

を行うと、ちょうどC++からsynchronizedMethod()を呼び出すことができます。

+0

確かに、これが代替手段の1つです。私が言ったように、私はコードを書き直すことにそれほど関心を持っていません。私は何が起こっているのか理解したいと思います。おかげさまで –

3

いいえ、明示的にMonitorEnter/MonitorExitは必要ありません。 The JNI guideによると、

... Javaプログラミング言語で同期構造を表現することが好ましい。たとえば、静的ネイティブメソッドが定義クラスに関連付けられたモニタに入る必要がある場合は、ネイティブコードでJNIレベルのモニタ同期を実行するのではなく、静的同期ネイティブメソッドを定義する必要があります。

(およびその逆はない)ネイティブコードからJavaメソッドを呼び出すあなたのケースが直接スペックで議論されていないにもかかわらず、反対はどちらか明記されていないので、私はそれが動作することをを引き受けます同様に。

+0

私はこれまでにこの情報を見つけましたが、これは逆の方向であるため、私はそれほど確かではありません。同期メソッドがmethod(){(this){メソッド本体}}と同様のものにコンパイルされていれば、問題はないと思います。私はこのために生成されるバイトコードと、jni呼び出しのエントリポイントが正確であるかどうか分かりません。 –

+0

@Eric Moors:同じバイトコードであることを絶対に確かめるために、バイトコードを調べる以外の方法はありません。しかし、私はそれがほぼ賭けるだろう。 –

関連する問題