You get deterministic multithreading just like you have mutable constants - you don't.
Instead, you use various forms of synchronization (including things like mutexes, semaphores, conditional variables, signals, etc.) to ensure that deterministic results (if necessary) are obtained from non-deterministic code. Of course, the more synchronization you use, the less parallelism you get from the code; therefore you only need minimal synchronization.
How to do this depends on the exact algorithm - there is no "silver bullet", this is the best way to do synchronization, which works for all completely different problems.
source share