Native Method Sync

I have a native method method defined as follows:

public static native int doSomething(); 

However, this method is not thread safe. So, I put the synchronized keyword on it, so now it looks like this:

 public static synchronized native int doSomething(); 

The problem seems to be fixed, but I'm not sure if this is really happening. Is it really? Is it blocking access to the method correctly?

+4
source share
2 answers

After reading the appropriate JLS section, there is nothing in JLS that prohibits the use of static and native in the method definition. According to the relevant JVM specification:

Method-level synchronization is performed implicitly as part of a method call and return (§2.11.8). The synchronized method is highlighted in the pool constant structure of the continuous process pool (§4.6) by the flag ACC_SYNCHRONIZED, which is checked by the method invocation instructions. When a method is called for which ACC_SYNCHRONIZED is set, the executable thread enters the monitor, calls the method itself, and exits the monitor whether the method call completes normally or abruptly. While the execution thread is running, the monitor belongs; no other thread can enter it. If an exception is thrown when the synchronized method is called, and the synchronized method does not handle the exception, the monitor for the method automatically exits to the exception from the synchronized method.

Because of this, the generated bytecode does not have any monitorenter or monitorexit , as the synchronized block does. The only thing generated in this case is invokestatic to invoke the static method. This command is generated if you call the static native synchronized method, the static native method, or the static method.

Here is an example of the 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"); } 

Generated Byte Code:

 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 } 
+5
source

Well, he makes access to the method mutually exclusive. If this is your idea of ​​proper thread safety, then I really believe that it is.

[Edit:] Of course, there is no way to tell you whether a method is thread safe or not just its signature. In fact, even the source of the method may not have enough information. Thread security is the synchronization of access to resources. If your method does not have access to any resource, then its thread safety even without a “synchronized” keyword.

A synchronized keyword does something thread safe if it synchronizes access to resources, i.e. your class has a private field, and every method that modifies it is synchronized.

+2
source

Source: https://habr.com/ru/post/1483698/


All Articles