The Basic Task Implementing Threading

In Chapt er 11 , we discussed the support Java provides for threading, both in the language and in the core libraries. In this chapter, we take a much more pragmatic point of view. The heart of this chapter is a set of idioms and usage guidelines intended to help you use threads safely and effectively in your applications. As part of this, well reimplement the bank example as a threadsafe application and, as a final example, talk about how to implement a general-purpose pooling mechanism. By the end of this chapter, you should have a complete understanding of how to use threads in a distributed application.

12.1 The Basic Task

Lets walk through the bank example again, this time looking at everything from the point of view of threads. The first problem is, of course, to discover where the threads are. Recall that we have three basic executing pieces of code: the server, the client, and the launch code. Of these, the server must be absolutely threadsafe. As we discussed in Chapt er 11 , RMI creates multiple threads. It will gleefully dispatch multiple threads into a single server object if multiple clients simultaneously make method calls on it. If you dont take this into account while implementing the server objects, the application will fail. The launch code, on the other hand, rarely needs to use multiple threads. Its executed once to configure and launch the application. Launch code is not complex, nor does it need to handle multiple tasks simultaneously. Making launch code threadsafe is usually a waste of time. Client code occupies the middle ground. Many clients are fairly simple programs and are single- threaded, or in the case of Java Swing, dual-threaded. However, in the typical client program, most activity occurs as a response to user interaction. The user clicks a button or slides a slider, and then something happens. Consequently, threading is not an issue for most clients. There are three important exceptions to this: when a client needs to receive an asynchronous callback from a server, when a client wishes to download a large data set in the background, and when a remote method call takes a substantial amount of time. In the final case, you probably dont want the GUI to stop responding simply because a remote method call is executing. Well discuss these in more detail in Chapt er 21 . Having said that, in order to make the bank example threadsafe, well worry only about objects that are in the servers JVM. In particular, this means we need to focus on Account_Impl . However, it also implies that we need to pay attention to our data objects. Instances of Money are required by our remote interface and are used in both the client and the server. As a rule of thumb, data objects should always be made threadsafe. This is because the client and server are likely to evolve independently, and, over time, they will use the data objects in different contexts. It is quite possible that in some future version of your application there will be multiple threads accessing a data object at the same time, even if this isnt the case in the current version of the application. In general, data objects shouldnt make assumptions about how they are going to be used in either the server or the client. And this means that, unless it requires significant effort, they should be made threadsafe as a default development procedure.

12.2 Guidelines for Threading