Search code examples
javamultithreadingjava-native-interfacenativejava-memory-model

Examples for thread divergence actions and external actions in the Java Memory Model


I'm currently learning about the Java Memory Model and I came about the different kinds of Actions.

There are two of them which I don't fully understand:

  • External Actions and
  • Thread divergence actions

Please explain those two action types and give examples for them and for their special properties regarding compiler-reordering and happens-before relation. Oh, and are native calls also external actions?

I think they wouldn't define thread divergence actions if there was nothing special about them. So what makes them special so that they need to be defined as a special kind of action?


Solution

  • The existing answer already correctly defines what these actions are.

    As for the reordering: look at the following example of a thread-divergence action:

    class ThreadDivergence { 
    
      int foo = 0; 
    
      void thread1() { 
        while (true); // thread-divergence action
        foo = 42; 
      } 
    
      void thread2() { 
        assert foo == 0; 
      } 
    }
    

    You would expect this assertion to never fail. Without thread-divergence actions, this could not be guaranteed because the unreachable definition of setting foo = 42 could be reordered to be executed first. This is forbidden by the JMM.

    Similarly, external actions are added to avoid surprising outcomes:

    class Externalization { 
    
      int foo = 0; 
    
      void method() { 
        jni(); // external action
        foo = 42; 
      } 
    
      native void jni(); /* { 
        assert foo == 0; 
      } */ 
    }
    

    Assuming that the JNI method was implemented to run the same assertion, you would not expect this to fail. The JIT compiler cannot determine the outcome of anything external such that the JMM forbidds such reorderings, too.