Something is going to change. I don't think I'm the only one who can feel it. We are seeing an impedance mismatch between our applications, the languages we use to write them, and the underlying hardware. The mismatch is slowing development, and customers are becoming less and less tolerant of that.
First, people are wanting to decompose applications and use pieces of them. Look at mash-ups, web services, RSS, and other similar technologies. The application that starts at line one and ends at line N has long been gone, but now we are seeing applications where every component is not always running together, not in application space nor on servers themselves.
Finally, hardware is scaling horizontally more than vertically, meaning we are going to see more cores to improve performance rather than more cycles. In order for applications to scale, they are going to have to scale horizontally as well.
The trouble is, as it stands today, componentizing applications and scaling them horizontally is hard. It is also more and more necessary. I think we are near the tipping point in an evolutionary change. The last evolutionary change was the application virtual machine (both the Java Virtual Machine and the CLR), which separated applications from the underlying hardware: input, output, memory management, etc. What it didn't do was remove from applications the onus of knowing where or when something was going to happen. That is what's coming.
The key to the next evolution is spacial and temporal isolation. This is possible today, just as building a highly-available multi-threaded application was possible 20 years ago using low-level languages. The difference is that it will now be virtualized in some fashion.
The paradigm change will push developers into writing more independent blocks of code that are known to be independent, with a VM that handles scheduling those blocks and communicating between those blocks. Inter-task communication will be allowed only at the beginning and end of blocks.
The concept is illustrated well with Stackless Python. Each tasklet exists independently with communication occuring at the beginning and end of the tasklet.
Once the application is properly broken into the tasklet concepts, the underlying compiler and VM will handle spacial and temporal translocation. Spacial translocation will allow a tasklet to run "anywhere", be it a seperate processor or a seperate system. Temporal translocation will allow tasklets to be run in near-arbitrary order and with arbitrary concurrency. Near-arbitrary order means the VM, as time goes on, will be able to predict which tasklets need to be run in which order. Arbitrary concurrency means that, assuming order is properly maintained so inputs match outputs, any tasklet can run concurrently with any other tasklet.
I believe that, somewhere, somebody has already begun the solution. My goal now is to find it. In 1998, I started using Java because I could sense the evolution inherit with it; I'm expecting that, by 2010, I'll be using "the next thing" and it will be in broad use by 2013. I'll let you know when I find it.