Don't know what to tell you, man.
You literally have to do it in any Java application when you are doing heavyweight operations off of the event dispatch thread, otherwise the interface locks up.
Certainly in the behavior modeling work I do, the amount of threading is more than normal developers would encounter, but in the IDE application development work I've done, even that uses threading a lot.
Again, not taking about the kind of stuff you seen to be alluding to, which is being down huge tasks into a ton of parallel pieces to leverage parallel processing. Just talking about normal application development where you have various independent tasks that don't rely in each other, and thus can be easily separated off into threads. One is hard, the other is routine.
Yeah, that's not really kosher, at least in Java. That's why the sun docs specifically talk about not doing large operations on the EDT, and why they have various helper classes specifically designed to merge the with of different threads into the EDT stuff. Anyone who worked with Swing, for instance, basically had to understand this stuff.
Just as a super simple example, you have menu item that does some big operation like saving a large file. If you do that on the EDT, directly on the stack from the menu listener, then the entire UI is going to freeze until that operation is done. That sucks. Even in cases where you don't want the user to do other stuff, you still don't usually just want to use the EDT for that, because it gives the impression that the application is broken, since it doesn't respond to anything at all.
And in those kind of tasks, they are independent from the other stuff the user is doing. It's easy to put them into a separate thread. There's no reason to make the user wait, since it's not going to impact the next thing they do.
Now, with the complex simulation environments I work with, the threading can potentially be more complex, but only the absolute oldest ones are single threaded. All the modern systems use multiple threads, because it lets us use the hardware more effectively. And because there are generally different areas of the application which can be largely severed from each other. The synchronization pieces are not trivial to make work, and all threads are not using at maximum load all the time, but multithreaded programming is a pretty standard thing.