Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Write high-performance RMI servers and Swing clients - JavaWorld - April 1999

Write high-performance RMI servers and Swing clients - JavaWorld - April 1999

Tutorial Details:

Write high-performance RMI servers and Swing clients
Write high-performance RMI servers and Swing clients
By: By Andy Krumel
Learn to implement asynchronous callbacks to Swing-based applications
ometime when you have a few minutes to burn, cruise into your local discount brokerage firm and watch the brokers operating the service counter. During a typical lunch hour, customers crowd the service counter like software engineers ravaging a convention booth giving away free t-shirts. The most effective brokers help multiple customers fill out forms, process checks, direct customers to the appropriate prospectus, and answer the phone simultaneously. The brokers not destined to make a living in the world of "churn and burn" simply serialize all of their tasks: help a customer fill out a form, or handle a phone call, or process a check, or -- you get the idea. The efficient broker keeps the line moving by handling multiple tasks concurrently, while the inefficient broker lets the tasks queue up as he or she works on a single task.
Which broker type best resembles your RMI, CORBA, or DCOM server process? Does your process perform synchronous writes to the log while executing client requests? Are client callbacks executed within the same method (process thread) that forced the notification? Does your server process perform callbacks in synchronized blocks? If you answered affirmatively to any of these questions, your process may resemble that of the inefficient broker. This article will provide techniques for improving the efficiency of your server, enabling it to handle more clients and return control to client processes more quickly.
Our example distributed program, SouthBay, provides a client application that allows users to bid on products and provides realtime updates on the current high bids. The client application interacts with a server application that maintains the current product bids and notifies clients when it receives a new high bid. This application uses RMI to illustrate the programming techniques, but the techniques are equally valid for CORBA-, DCOM-, or TCP-based applications.
SouthBay application overview
The SouthBay distributed application provides the user an application that displays the current list of products for sale and a server application that maintains the current high bid and informs registered clients when a price changes. Figure 1 shows the appearance of SouthBay's Swing-based, client user interface.
Figure 1. SouthBay client screenshot
Selecting an item in the Products list causes the product detail to be displayed in the Current Product panel, which shows the product ID, description, current bid, and current bid acceptance time. This being a startup e-commerce venture, we don't have to make a profit for the foreseeable future, so no provision has been made to track users or allow them to pay for a product; after all, there has to be some incentive for them to upgrade. Clicking on the Bid on Item button pops up an input message panel into which the user can enter a new bid (Figure 2).
Figure 2. Enter a new bid dialog
Pressing the OK button causes the client application to submit the bid to the server. If the new bid is higher than all previous bids, the new bid replaces the previous high bid and the server broadcasts the new bid to all registered clients. Our client registers with the server when it starts up and unregisters when the user closes the application.
RMI and threads
Since this article deals with server-side threading techniques, I would like to talk a little about how RMI uses threads to handle client requests before proceeding into the design of the SouthBay application. Although we're dealing with RMI, the principles discussed in this section equally apply to CORBA and DCOM.
Many programmers are unsure how RMI handles concurrent calls to a single RMI object; and compounding the confusion, the RMI specification doesn't set a policy for how calls should be dispatched by the RMI system. Essentially, a separate thread dispatches every RMI call. The implication for RMI objects is they must be thread safe, since the object may have to handle multiple requests simultaneously.
The RMI specification doesn't identify a specific thread-dispatching policy, so each RMI implementation exhibits different runtime characteristics. In addition to the implementation that ships with the JDK, BEA Software provides an implementation with its WebXpress application server. One of the main differences between the two RMI implementations is the remote method call dispatching mechanisms. Of the two, the standard Sun implementation has the least efficient threading architecture, for it suffers from several shortcomings:
There is no configurable upper limit on the number of server threads to handle client requests : Failure to enforce an upper limit means the server could be overwhelmed with requests and thereby exhaust its resources. Developing a solution to this problem is difficult at best because RMI doesn't provide a hook for implementing custom threading policies as it does for custom sockets.
Call-dispatching threads aren't reused : This is a very simplistic means of implementing a multithreaded server that wastes resources and limits scalability. To demonstrate this behavior, I ran five SouthBay clients and alternated bid requests. Figure 3 shows the thread list at a breakpoint in the server at the time of servicing the first client update request:
Figure 3. RMI dispatcher thread list at first client update request
I've highlighted the RMI dispatcher threads, the blue arrow indicates the thread handling the client request. Figure 4 shows the stack trace after updating a bid 67 times:
Figure 4. RMI dispatcher thread list after 67 updates (still the original five processes)
Notice that many of the original threads have died, and that new threads have been created in their place. Figure 5 shows the thread list after stopping the first batch of processes and starting five additional clients:
Figure 5. RMI dispatcher threads after stopping first batch of clients
Imagine how this would scale on a server under heavy load of multiple requests per second.
Despite these shortcomings, RMI is adequate for applications that don't involve handling a large number of concurrent users. BEA WebXpress provides an alternative RMI implementation with vastly improved scalability.
The key point to take away from this is that RMI server processes are multithreaded and your RMI implementation must be prepared for the load.
Anatomy of a callback
The SouthBay's RMI objects will run in a multithreaded environment, but we need to ensure the design facilitates an efficient use of the server's resources. Ideally, the design should minimize the number of client RMI requests so the server can scale to handle more users. An effective means of reducing the number of client requests is to implement a callback model for asynchronous state change notifications.
When using server callbacks, the server's broadcast forcefully synchronizes the clients' state with the server. Without using a callback model, clients would have to continuously query the server for updates, thus wasting valuable network resources and server processing time.
Implementing an RMI application that supports callbacks is fairly straightforward. The first step is to declare two remote interfaces: the server-side interface and the client-side interface. The server-side interface defines two registration methods and at least one other method that triggers the callback. I will call this the state change method. The registration methods accept a remote reference to the client-side interface as their sole parameter, although some implementation may call for additional parameters. The client-side interface declares one or more methods called by the server when some client invokes one of the server's state change methods.
The client-side and server-side remote interfaces for the SouthBay application are very simple. The client-side interface is called Bidder and declares two callback methods:
package callback;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Bidder extends Remote {
void updateBid(Bid b) throws RemoteException;
void serverShuttingDown() throws RemoteException;
}
The server-side interface is called Auctioneer and declares two registration methods, a single state change method, and a query method that returns the current bids:
package callback;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Auctioneer extends Remote {
BidException;
void addBidder(Bidder b) throws RemoteException;
void removeBidder(Bidder b) throws RemoteException;
Bid[] getCurrentBids() throws RemoteException;
void updateBid(Bid b) throws RemoteException,
}
The registration methods normally follow the AWT event model convention for registering event listeners by using the naming convention addXxx(Xxx) and removeXxx(Xxx) . Since the Auctioneer notifies Bidder instances of current bid changes, the two registration methods are called addBidder() and removeBidder() . The state change method, called updateBid() , takes a Bid instance and throws a BidException if the bid isn't valid due to a low price or the product is not currently for sale.
Bids and products are represented using the Bid class, which is defined as:
package callback;
public class Bid implements Serializable {
private String fId;
private String fDesc;
private URL fImage;
private Date fTimeOfBid = new Date();
private double fCurrBid;
private transient ImageIcon fIcon;
public Bid(String id, String desc, URL image, double price)
public String getId()
public String getDescription()
public Icon getIcon()
public Date getTimeOfBid()
public double getCurrentBid()
public int comparePrice(Bid b)
public int comparePrice(double p)
public void updateBid(double price)
public boolean equals(Object o)
public String toSt


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Write high-performance RMI servers and Swing clients - JavaWorld - April 1999

View Tutorial:
Write high-performance RMI servers and Swing clients - JavaWorld - April 1999

Related Tutorials:

Design networked applications in RMI using the Adapter design pattern
Design networked applications in RMI using the Adapter design pattern
 
Jini-like discovery for RMI
Jini-like discovery for RMI
 
Implement a J2EE-aware application console in Swing
Implement a J2EE-aware application console in Swing
 
Deploy code servers in Jini systems
Deploy code servers in Jini systems
 
Cache SOAP services on the client side
Cache SOAP services on the client side
 
Integrate EJBs with CORBA
Integrate EJBs with CORBA
 
Business process automation made easy with Java, Part 1
Business process automation made easy with Java, Part 1
 
Should you go with JMS?
Should you go with JMS?
 
TRMI
TRMI
 
FastParser 1.6.3
FastParser 1.6.9.1 XML Edition FastParser is a Java Xml parser High performance XML parser (benchmarks* : up to +100% faster compared to Xerces and JDK1.4 integrated parser) SAX Level 1 and 2 compliant DOM support JAXP compatibility Names
 
Wi.Ser (WidgetServer) unified rich client framework
Wi.Ser is a Java/XML server-side GUI-framework which enables an application to run as either a monolithic Swing application, a thin-client/server Swing application, or as a Web application without any change!
 
Building Highly Scalable Servers with Java NIO
Building Highly Scalable Servers with Java NIO I/O Event Handling The I/O architecture of our router was strongly inspired by the Swing event-dispatch model. In Swing, events generated by the user interface are received by the JVM and stored in an even
 
JLAN Server v3.3
JLAN Server v3.3 JLAN Server is a high performance JavaTM based file server supporting Windows file sharing (SMB/CIFS), NFS and FTP protocols. Write your own virtual filesystems with the core server handling all protocol exchanges with the client. Incl
 
JLAN Client 3.0
JLAN Client is a JavaTM based library that implements the various protocols used by Windows Networking (NetBIOS over TCP/IP, SMB/CIFS and DCE/RPC).
 
OIL (Objects in a Line)
OIL (Objects in a Lile) provides a queue API and its implementation which is required by many server applications which stores client requests permanently in order. OIL provides: Queue which provides sequential access. Index which provides random acce
 
Networking our whiteboard with servlets.
Find out how to easily replace the RMI and sockets networking layers with servlets.
 
What is Persistence Framework?
What is Persistence Framework? What is Persistence Framework? A persistence framework moves the program data in its most natural form (in memory objects) to and from a permanent data store the database. The persistence framework manages the
 
Free JSP, Free EJB and Free Servlets Hosting Servers
Free JSP, Free EJB and Free Servlets Hosting Servers Free JSP, Free EJB and Free Servlets Hosting Servers Web roseindia.net Other Free Hosting Services MyCGIserver - Free Hosting server provides the following support with the free account: JSP
 
Free JSP, Free EJB and Free Servlets Hosting Servers
Free JSP, Free EJB and Free Servlets Hosting Servers Web roseindia.net Free JSP, Free EJB and Free Servlets Hosting Servers MyCGIserver - Free Hosting server provides the following support with the free account: JSP 1.1, Servlets, Apache Cocoon,
 
Techniques used for Generating Dynamic Content Using Java Servlets.
Techniques used for Generating Dynamic Content Using Java Servlets. Techniques used for Generating Dynamic Content Common Gateway Interface (CGI) For any web application high performance and timely delivery are key ingredients to competitive
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.