<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 23/01/2024 16:56, Jurgen Doll wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:op.2h0bwcdn0ae2rt@admin-pc">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <style type="text/css">body { font-family:'Calibri'; font-size:13px}</style>
      <div><big>Hi John and others,</big></div>
      <div><big><br>
        </big></div>
      <div><big>I don't think we are entirely on the same page, so
          here's the objective.<br>
          <br>
          The Goal: To determine if the FX animation thread and a SINGLE
          other thread can access Animation in a safe manner wrt play,
          stop, and resume.<br>
        </big></div>
    </blockquote>
    The number of threads is irrelevant really, it's either thread safe
    or it isn't.<br>
    <blockquote type="cite" cite="mid:op.2h0bwcdn0ae2rt@admin-pc">
      <div><big><br>
          Non Goal: Multi-threaded access of Animation play, stop, and
          resume is NOT a goal.<br>
          <br>
          Wrt play() and resume(), it is ALWAYS safe to call them on a
          background thread because at this point the Animation isn't
          being processed by the FX thread as the "Animation" isn't
          contained in the AbstractPrimaryTimer receivers array.<br>
        </big></div>
    </blockquote>
    <p>I'm afraid that is incorrect.  The fact that your animation is
      not running doesn't mean that AbstractPrimaryTimer isn't in use by
      other animations that are running.  These other animations are
      using the receivers array, and may be modifying it or reading from
      it from the FX thread.</p>
    <p>When you start your animation on a different thread, you are
      accessing these fields with a different thread, and modifying
      them.  Since the JVM is free to cache values and do other fancy
      things (like reordering read/writes) in the absence of
      synchronized/locking, there is no guarantee that the FX thread
      will see those modifications until these are flushed to main
      memory (or caches are synced).  Even then, the FX thread may have
      these values cached somewhere, and so it may not go all the way to
      main memory to see if its assumptions are now incorrect.  The only
      way to ensure this is with proper use of synchronization.</p>
    <p>So a hypothetical scenario:</p>
    <p>- AbstractPrimaryTimer has no receivers<br>
      - A receiver is added via the FX thread, slot 0 is now filled and
      receiversLength is now 1.  Due to cache lines being large, it also
      read slot 1 (which is null)<br>
      - You start your animation on another thread.  Since you didn't
      see the receivers array yet, you may see one of these states:<br>
          - The change from the FX thread was flushed to main memory,
      and you see [X, null] and receiversLength = 1<br>
          - The change from the FX thread was partially flushed, and you
      see [X, null]  and receiversLength = 0 (!!)<br>
          - Nothing was flushed yet, and you see [null, null] and
      receiversLength = 0</p>
    <p>Now, you can see that it would be very dangerous to proceed to
      modify the array based on half flushed information.  Something
      similar happens when you are the first to start an animation, and
      then another is started later.  If the changes of your thread are
      not flushed yet (or partially) then the FX thread will act on
      partially flushed data, or even see no receivers yet at all...<br>
    </p>
    <p>--John<br>
    </p>
    <br>
  </body>
</html>