Multi-threaded safety is simply due to JIT controlling the visibility of the newly compiled code. First flush, then make it visible for execution, can't go wrong with that and scheduling won't matter.
Things get a lot more complicated when it comes to code patching, but the principle is similar.