Hi Terris,
I have been lucky because I have been able to do research in High-Performance Computing and I got a lot of experience with concurrent code. I learn a lot of ways to screw up things, and a lot of patterns to avoid them.
In my recent experience, each time that I have found a concurrent code programmed by someone, even with some experience, I had started to fear the worst. I have ever seen supposed experts coding awful mistakes that fail time to time.
For example, I taught some of them to some students back in 2013 when I implemented one of the most easy to maintain versions of the RAFT consensus algorithm, because the teacher was unable to write good concurrent code. Or I was rejected in a job interview, because they put me a concurrent problem, first I did the simple solution, so they could understand that, then they asked me to improve it, and I did a so highly performant solution that they did not understand the result, and they said that it could not work. (Ok, it is fair because the code should easy to understand by all, but my repertoire is full of techniques, so just ask which one do you want).
And what I saw is that concurrent programming is really hard. There are thousands of ways to screw it up., Even in the worst implementations, in which programmers put everything under a lock and slows down everything so much, that two threads are slower than one, it is still a risk.
So, I am glad that new languages do not encourage preemptive multithreading, instead they promote cooperative multithreading; and at the same time, that they offer a preemptive multithreading solution through secure message pass (aka WebWorkers).