From the Manageability weblog comes the question and some answers about the ability to hide concurrency issues through one form of abstraction or another.
Functional programming is dinged for not having a concept of state or time. This is a misstatement. There are several ways to represent state and time in functional languages. It's just that none of them are that much better than they are in other styles of programming.
Toward the end of the item there are some subtle observations...
In short, it's all about coordination, and if you can build effective coordination mechanisms then you're on the right track to solving the real problem. To say that it can be abstracted away isn't solving the problem, it's denying the problem exists.
Ah, but what the item does not address is what are the various ways of abstracting concurrency. Abstracting does not always mean "hiding 100 percent".
The key is to build appropriate abstractions for representing concurrency, rather than hiding concurrency. For example an effective technique for avoiding deadlock is to assign an order for aquiring resources.
The difficult attempt would be to hide the fact that multiple consumers are competing for multiple shared resources. The typical attempt would be to explicitly code the competition using some low level locking mechanism.
The "just right" attempt would be to evolve an API that describes the desired order of consumption, holding on to multiple resources (or not), and the exceptional behavior for waiting.
One thing we need are better modeling and testing frameworks for concurrency scenarios.
We can also simplify the API evolution through higher level concurrency mechanisms like tuple spaces. Tuple spaces provide a few simple operations that act as building blocks for a wide variety of scenarios. They can be applied to in-process, multi-process, and persistent or transitory scenarios.