问题描述
我有一个像这样定义的本机方法:
I have a native method method defined like this:
public static native int doSomething();
但是,此方法不是线程安全的。所以,我在其上放了一个 synchronized
关键字,所以它现在看起来像这样:
However, this method is not thread-safe. So, I put a synchronized
keyword on it, so it looks like this now:
public static synchronized native int doSomething();
这似乎可以解决问题,但我不确定它是否确实存在。这有效吗?它是否实际上正确锁定了对方法的访问权限?
This appears to fix the problem, but I'm not sure if it actually does. Is this valid? Does it actually properly lock access to the method?
推荐答案
阅读相关的,JLS中没有任何内容禁止<$ c来自方法定义的$ c> static 和 native
。根据
After reading the relevant JLS section, there is nothing in the JLS which prohibits static
and native
from being in the method definition. According to the relevant JVM spec:
因此,生成的字节码没有任何 monitorenter
或 monitorexit
指令,作为 synchronized
块。在这种情况下,唯一生成的是 invokestatic
,以便调用静态方法。如果您调用静态本机同步
方法,静态本机
方法或<$ c $,则会生成此指令c> static 方法。
Because of this, the bytecode that is generated does not have any monitorenter
or monitorexit
instructions, as a synchronized
block does. The only thing that is generated in this case is invokestatic
, in order to invoke the static method. This instruction is generated if you call a static native synchronized
method, a static native
method, or a static
method.
以下是生成字节码的示例代码:
Here's some example code with the generated bytecode:
public static void main( String[] args ){
doSomething1();
System.out.println("Now do 2");
doSomething2();
System.out.println("native java");
doSomethingJava();
String s = "test";
synchronized ( s ){
int x = 9 + 5;
}
}
public static native void doSomething1();
public static synchronized native void doSomething2();
public static synchronized void doSomethingJava(){
System.out.println("synchronized");
}
生成的字节码:
Compiled from "test.java"
class test {
test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method doSomething1:()V
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: ldc #4 // String Now do 2
8: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
11: invokestatic #6 // Method doSomething2:()V
14: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
17: ldc #7 // String native java
19: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: invokestatic #8 // Method doSomethingJava:()V
25: ldc #9 // String test
27: astore_1
28: aload_1
29: dup
30: astore_2
31: monitorenter
32: bipush 14
34: istore_3
35: aload_2
36: monitorexit
37: goto 47
40: astore 4
42: aload_2
43: monitorexit
44: aload 4
46: athrow
47: return
Exception table:
from to target type
32 37 40 any
40 44 40 any
public static native void doSomething1();
public static synchronized native void doSomething2();
public static synchronized void doSomethingJava();
Code:
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #10 // String synchronized
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
这篇关于本机方法同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!