I couldn’t stop myself from reading engine source code. The answer is actually pretty easy to find, if one knows where to look…
ParallelFor uses FEvent to tell the game thread that the individual tasks that are created have finished. FEvent is basically an abstraction of thread synchronization using events, and behaves like Windows Event objects (on Windows it’s just a wrapper around those). This means, that whenever the game thread gets informed of a parallel-for task being finished, there’s a memory barrier in place, so that the data in the main thread is guaranteed to contain all changes done within the parallel for.
In other words: Parallel For is perfect for what I want to do, and no additional synchronization is needed.