Whether memory is shared by default (threads) or explicitly (processes) is a little bit of a red herring. The thing that makes parallelized designs hard happens at a higher level: it's that whatever your shared resources are (files, databases, shared memory, in-core databases hanging off message listeners, etc), you have to find a design that allows things to be shared and correct, and that's a hard balance to strike.