Earlier quoted context omitted.
That doesn't work as well as you think it does because entities cannot think on their own. They need to refer to global shared state all the time.
In low level audio you have something similar: there's a thread that pulls audio data all the time and it can't stop; at the same time you have potentially lots of things happening in other threads, including the UI one. You can always find ways of minimizing the synchronization overhead by e.g. having a single fast entry point to any changes that happened since the last cycle. With audio you basically end up passing…
Copying and passing immutable data around is not always fast enough and definitely not trivial to merge the results back.
In summary, it is a hard problem with no general solution. If you could solve it, then you have solved multithreading design for any problem.