Add `synchronized(lock)` around array mutations in `addPulseReceiver`/`removePulseReceiver`/`addAnimationTimer`/`removeAnimationTimer` and around snapshot-taking in `timePulseImpl`. Iteration remains outside the lock. `updateAnimationRunnable()` is also called outside the lock to avoid nested locking.
This preserves the existing copy-on-write design - the lock just ensures it works correctly across threads. Performance impact is minimal: the lock only covers field reads/writes, not the per-frame iteration. **Testing:** New `AbstractPrimaryTimerThreadSafetyTest` with `testConcurrentAddAnimationTimer` - 8 threads add timers simultaneously, repeated 100 times. Fails 100% without fix. Reuses `AbstractPrimaryTimerStub` from existing tests. All existing animation tests pass. In JPro, this often caused a Deadlock during startup. This might have caused many bugs, which are very hard to reproduce. ------------- Commit messages: - JDK-8377850 Changes: https://git.openjdk.org/jfx/pull/2074/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=2074&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8377850 Stats: 206 lines in 3 files changed: 142 ins; 9 del; 55 mod Patch: https://git.openjdk.org/jfx/pull/2074.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/2074/head:pull/2074 PR: https://git.openjdk.org/jfx/pull/2074
