Another cool product is Disruptor - they have figured out a good, fast way to do message passing that minimizes the need for concurrent data structures between worker threads. (Provided of course you can model your app in that way). Under the hood, they have some crazy dep memory barrier based stuff, but for most of the programmers on a team, thinking about that stuff is just not needed. (as an aside, I think if Beautiful Code 2 was being written, I think Disruptor should be included, that source code is downright inspiring.)
The point being, once you have a good, trusted and vetted set of primitives, and are willing to put a little effort into working in a paradigm someone else sets, you get a lot of benefit. This is no different than using RoR or Django instead of rolling your own web framework.
My point was that multi-threaded programming hasn't taken off because it hasn't needed to. We just get some really smart experienced guys to write our infrastructure that encapsulates thread use and all of us get to reuse that.
I really don't get on with this mindset that someone else can fix it.
In fact, using any thread or concurrency mechanism in JEE code is considered a code smell, you should be handling it with the Spring/JMS/Jboss setup
I've had the sort of career that involved highly-optimised in-memory databases, high-volume, low-latency payment processing and stuff like that. So I'm used to dealing with this stuff direct.
MMmmm..... yeah it has. I'll agree on the silver bullet, but I don't think they need one.
Threads are all over the place, and easier than ever to use. They do require intelligence to use well, and people to think about things like locking strategies, but they really are not all that hard. It amazes me that people seem to be so scared of them for some reason.
Perhaps it's the problem domain I work in (back-end server systems) but I come across them all the time. When dealing with lots of distinct tasks for lots of distinct clients you can make good use of threads without needing to do the kind of hard-core mathematical analysis that you would apply to splitting single tasks across parallel systems.
(And no, I'm not suggesting that a one-thread-per-client model is a silver bullet, there are more efficient async ways of doing things)