Modern CPUs usually feature separate instruction and data caches, so effectively, even if from a software PoV, everything is coming from a single memory space, there are physically separate busses and memories for instructions and data ("harvard", which is used for all reasonably fast CPUs nowadays).
There are also multi-port memories able to sustain several accesses simultanously. There is a great variety of architectures, for example DSPs or GPUs may have different memory organization than traditional CPUs.
In computers, with something like an x86 or an ARM, with an OS and applications, code memory is separate from data memory (there are attributes in MMU mappings), code is read-only. Except during on-the-fly dynamic compilation, or some library linkage, code is never modified through data accesses, there is no self-modifying code. It is nowadays far more efficient to have separate code and data memories for first level caches.
Many years ago, when one couldn't put billions of transistors on a die, there were shared or off-chip caches, and sometimes data accesses could effectively stall instruction fetches.