It's (with caveats, of course):
- a thread crashing will not bring the system down
- a thread cannot hog all processing time as the system ensures all threads get to run. The entire system is re-entrant and execution of each thread can be suspended to let other threads continue
- all CPU cores can and will be utilized transparently to the user
- you can monitor a thread and if it crashes you're guaranteed to receive info on why and how it crashed
- immutable data structures play a huge part of it, of course, but the above is probably more important
That's why Go's concurrency is not that good, actually. Goroutines are not even half-way there: an error in a goroutine can panic-kill your entire program, there are no good ways to monitor them etc.