|
I would like to know how to write a thread-safe client/server program in Java. How should I approach the threading? What sort
of issues should I be aware of?
Thread-safe programming is only necessary if you have data that can be modified by more than one thread at a time. In a client/server
situation, usually the server has multiple clients. If all those clients do is read data from the server, and if no other
programs are modifying that data, then you have nothing to worry about. But if those clients can change shared data on the
server, they must not be allowed to conflict with one another. Normally, if two clients try to change shared data, you have
to hope that the first client is able to finish with the data before the second client begins to modify it. This situation
is called racing.
Under these circumstances, the outcome depends on how the underlying scheduler happens to allocate time to the various clients' requests. In the case of Java, one doesn't know what the underlying scheduler's policies are (because they're platform-dependent, or natively implemented), but even with a known scheduling policy, the actual allocation will depend on the availability of various resources (typically I/O) and user inputs; therefore it is never readily predictable.
Thread-safe design replaces racing situations with choreographed access to shared data. In Java, thread-safe design gets a lot of support from the underlying language (through synchronized blocks) and the standard class library (through the wait/notify mechanism in Object).
The simplest way to make a thread-safe design is to use synchronized blocks so that only one client can access the server at any one time. All other clients must wait until the server finishes with that client. Obviously, such a solution doesn't scale well as more clients are added, since clients will have to wait a long time for their turn to access the server.
In fact, if a poorly implemented server entered an infinite loop during a call by one client, then all its other clients would wait forever. This is an example of a general problem called starvation, which has to do with situations where a client never finishes its task because one or more other clients have monopolized the resource it needs.