gpt4 book ai didi

java - native 方法同步

转载 作者:搜寻专家 更新时间:2023-11-01 01:53:50 24 4
gpt4 key购买 nike

我有一个这样定义的本地方法方法:

public static native int doSomething();

但是,这个方法不是线程安全的。所以,我在上面放了一个 synchronized 关键字,所以它现在看起来像这样:

public static synchronized native int doSomething();

这似乎解决了问题,但我不确定是否确实如此。这有效吗?它是否真的正确地锁定了对该方法的访问?

最佳答案

看完相关JLS section , JLS 中没有任何内容禁止 staticnative 出现在方法定义中。根据relevant JVM spec:

Method-level synchronization is performed implicitly, as part of method invocation and return (§2.11.8). A synchronized method is distinguished in the run-time constant pool's method_info structure (§4.6) by the ACC_SYNCHRONIZED flag, which is checked by the method invocation instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.

因此,生成的字节码没有任何 monitorentermonitorexit 指令,而 synchronized block 有。在这种情况下唯一生成的是 invokestatic,以便调用静态方法。如果您调用 static native synchronized 方法、static native 方法或 static 方法,则会生成此指令。

下面是一些带有生成的字节码的示例代码:

    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
}

关于java - native 方法同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16848282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com