While I agree that they can be difficult, they exist for a reason, and frankly, with some proper study of functional and parallel programming, they can be used correctly. Closures have been a part of programming since LISP and frankly, higher order functions and functional programming can solve a lot of problems quite nicely. Certainly, mutability makes that a bit more difficult, but it can be managed. Finally, figuring out what variables are captured in a closure is quite doable by static analysis, which would be a nice addition to some programming environments.
Threads are more difficult for sure, but there are frameworks that can provide some useful higher level abstractions to make there use a bit easier. Lower level usage can be quite difficult, but a bit of actual thought and design goes along way. Also, there are some really powerful tools for multithreaded debugging, they just aren't freely available.
Mainly, I've found that people that can't manage these abstractions just don't have enough background in operating systems (which also discusses basics of concurrency) and functional programming, topics that used to be required in CS education. They can be learned and it can increase your overall code quality and reduce some frustrations.