Scalability is quite an overloaded term, so I save myself some keystrokes here and don't provide a definition. A couple of years ago I read and article about scalability and summarized it as follows:
... your application is fully scalable, when separating it into modules and providing mediators for communication between these modulesWhat I was trying to say is that asynchronous, stateless, message-based communication is the way to go, when it comes to scalability.
In my code I've always tried to avoid state, because it makes concurrency harder and easily introduces bugs. Although I did my very best to write proper, bug-free concurrent Java code, after reading Brian Goetz's "Java Concurrency in Practice", I know that I've probably failed a lot of times. Nevertheless I was on the right track - shared stated is evil.
Stateless, message-based communication are the principals used in Scala's Actor library, which I'm playing around with right now.
Actors in Scala communicate by passing messages and thus don't share any state. Each Actor has an inbox, which queues incoming messages until they are being processed. Since we are talking about a library here, everything is being mapped to the underlying thread model of the platform (Java or .NET). There are two different implementations you can use: a thread-based approach, where each Actor gets its own thread or an event-based approach which is basically thread-less.
Before looking into Scala's Actors, I've always found message-based communication rather cumbersome to code. You have to implement listener interfaces, block until you receive a message or register at a topic, to receive a reply to your request. Scala's Actor library makes it rather painless to implement message-based communication, especially when it comes to handling incoming or outgoing messages. It encourages you to split your tasks and introduce concurrency, simply because it's so easy. No synchronization and no thread-handling.
I really think this a great approach to tackle the multicore-problem and with closures in Java we could introduce an easy to use framework to achieve the same.