I think that the standard concurrent programming material would be easier to understand if it were presented in pattern form. You are welcome to watch while I stumble around and figure out whether I am right.
I've heard people claim that concurrent programming is actually easier than sequential programming. Moreover, they didn't seem to be joking! In spite of spending several years thinking of concurrent programming, it has always seemed a lot harder to me. Concurrent programming is programming with multiple processes, which implies that several things can be happening simultaneously. Of course, "simultaneously" doesn't necessarily mean that they happen at the same time, it just means that you don't know which happens first, and that they might be happening at the same time.
One key pattern of concurrent programming is CriticalSection, which is what you use to keep processes from interfering with each other. You can think of CriticalSection as what you use to keep from having too much concurrency. But unwise use of CriticalSection can lead to DeadLock, LiveLock (or Starvation, but that can't be a name here), and ResourceContention, which are all problems that lead to other patterns.
These patterns work in a variety of ConcurrentExecutionEnvironments, each with its own ConstellationOfForces.
See also: http://www.cs.wustl.edu/~schmidt/patterns-ace.html