Java Reference
In-Depth Information
redundant servers rather than trying to eke out another factor of three increase on a
single server.
Of course, sharding introduces design issues of its own, particularly around consistency,
that aren't present in a single system. But it does offer you more scalability and redun‐
dancy than you'll ever get out of a single system, no matter how efficiently implemented.
Unfortunately, this increased performance doesn't come for free. There's a cost in pro‐
gram complexity. In particular, multithreaded servers (and other multithreaded pro‐
grams) require developers to address concerns that aren't issues for single-threaded
programs, particularly issues of safety and liveness. Because different threads share the
same memory, it's entirely possible for one thread to stomp all over the variables and
data structures used by another thread. This is similar to the way one program running
on a nonmemory-protected operating system such as Windows 95 can crash the entire
system. Consequently, different threads have to be extremely careful about which re‐
sources they use when. Generally, each thread must agree to use certain resources only
when it's sure those resources can't change or that it has exclusive access to them. How‐
ever, it's also possible for two threads to be too careful, each waiting for exclusive access
to resources it will never get. This can lead to deadlock, in which two threads are each
waiting for resources the other possesses. Neither thread can proceed without the re‐
sources that the other thread has reserved, but neither is willing to give up the resources
it has already.
Running Threads
A thread with a little t is a separate, independent path of execution in the virtual machine.
A Thread with a capital T is an instance of the java.lang.Thread class. There is a one-
to-one relationship between threads executing in the virtual machine and Thread ob‐
jects constructed by the virtual machine. Most of the time it's obvious from the context
which one is meant if the difference is really important.
To start a new thread running in the virtual machine, you construct an instance of the
Thread class and invoke its start() method, like this:
Thread t = new Thread ();
t . start ();
Of course, this thread isn't very interesting because it doesn't have anything to do. To
give a thread something to do, you either subclass the Thread class and override its
run() method, or implement the Runnable interface and pass the Runnable object to
the Thread constructor. I generally prefer the second option because it separates the
task that the thread performs from the thread itself more cleanly, but you will see both
techniques used in this topic and elsewhere. In both cases, the key is the run() method,
which has this signature:
 
Search WWH ::




Custom Search