From 1970 to about 2002 processors doubled in speed about every 18 months. So as a programmer all you had to do was wait and your program would go faster. The problem is that around 2002 the rules changed. Now they are not making bigger fast processors they are making smaller slower processors but putting them out in groups. The computer I am working on now has 4 cores, and Chips with up to 8 cores (and 4 threads per core) exist. Soon enough we will have chips with a lot more cores.
So if you write a program that is not at all concurrent you will find that you are using 1 core or thread, but the rest of the CPU is sitting there doing nothing. So if you have 16 cores 1 will be running your program and the other 15 are sitting there!
The problem with concurrency is that it is non deterministic. Which is to say that you don't know exactly what order different threads will do things in. Traditionally programmers have tried to solve this by using locks and the like. This has lead to a LOT of pain. Having some form of mutable state that more than one thread can access freely is often a formula for pain and heisnebugs!
Of late the trend has be to moving to functional languages which tightly control mutable state. There are two basic ways that functional languages handle concurrency. The first is by using message passing. This is best shown by Erlang. In Erlang there is in general no Shared state between processes. They communicate not by sharing memory but my passing messages. This should make sense to you as we are doing it right now. I am sending this information to you by sending you a message, not by you remembering it out of my brain! By switching to message passing most of the locking bugs simply go away. In addition messages can be passed over the network as well as within one node.
The other method is STM, which stands for Software Transcriptional Memory, This is present in clojure and Haskell (and others). In STM memory is shared but changes can only be made via a transaction. As the Database folks figured all this stuff out in the 1970's it is pretty easy to ensure that we get it right.
Actually I over simplified a bit, Clojure and Haskell can both do message passing, and Erlang can do STM.
Disclaimer I am the author of Programming Web Services with Erlang, which will be out in Early release in the next few weeks.