if (key != null) key.cancel();
...
}
Again I wonder: How does this realization per-form? And again I can answer: it performs well.
In principle, one Acceptor and one Connection-Selector are sufficient to keep an arbitrary number of connections open. Thus this realization shines in the category of scalability. But as the two threads have to communicate through the synchronized queue() method, they might block each other. There are two ways out of this dilemma:
1. A better realization of the queue
2. Multiple Acceptor/ConnectionSelector pairs
One solution could be realized by using a LinkedQueue (see Concurrent Programming in Java by Doug Lea). This data structure is synchronized with two independent locks – one for the head and one for the tail. This ensures that adding and remov-ing threads don’t block each other. Only if the queue is empty is there a possibility of mutual blocking, but this can be avoided with an extra check.
In comparison to this elegant approach, my sec-ond solution qualifies for the “brute force” category.
The load is balanced with multiple Acceptor/
ConnectionSelector pairs and the synchronization problem isn’t solved, but is somewhat reduced.
Unfortunately, this causes additional costs for con-text switches. Compared to Httpd, fewer threads are needed.
One disadvantage to NIOHttpd, in comparison to Httpd, is that for each request, a new Connection object with buffers is created. This leads to an addi-tional CPU cycle burning caused by the garbage col-lector. How large these extra costs are depends on the VM. However, Sun doesn’t tire of emphasizing that with Hotspot, short-lived objects are not a problem anymore.
Comparative Number Games
How much better does NIOHttpd scale than Httpd? Let’s play with a couple of numbers, but before I go into media res, be warned: the formulas and the numbers I’m going to find are highly specu-lative. Only the concepts’ performance is estimated.
Important context variables like thread synchro-nization, context switches, paging, hard disk speed, and caches are not considered.
First I estimate how long it takes to process r simultaneous requests for files with size s bytes, if the client bandwidth is b bytes/second. In the case of Httpd, this obviously depends directly on the number of threads t, as only t requests can be processed at a time. I assume that a corresponding formula looks like Formula 1. c is the constant cost for parsing, etc., that has to be paid for every
Java COM
8000 1000 0.89 1.13
8000 10000 0.44 2.25
8000 100000 0.07 13.5
8000 1000000 0.01 126
10000000 1000 1.00 1.00
10000000 10000 1.00 1.0
10000000 100000 0.99 1.01
10000000 1000000 0.91 1.1
d f o r–> ∞
MAY2002 53
Java COM
Interland
www.interland.com
Java COM 54 MAY2002
request. In addition, I assume I can read data faster from the disk than I can write it to the socket, my bandwidth is greater than the sum of the clients’
bandwidth, and the CPU is not fully utilized.
Therefore the server-side bandwidth, caches, and hard disk speed are not part of the equation.
However, NIOHttpd is not dependent on t. The transfer time l depends mostly on the client band-width b, the size of the file s, and the previously mentioned constant costs c. This leads to Formula 2, which estimates the minimum transfer time for NIOHttpd.
The quotient d (see Formula 3) is of interest since it measures the relationship of the perfor-mances of NIOHttpd and Httpd.
After closer examination (…and some rows of data), it becomes apparent that if s, b, t, and c are constant, d grows toward a limit. This limit can be easily calculated using Formula 4, which measures the limit of d for r –> ∞.
Thus, besides the number of threads and con-stant costs, the connection’s length s/b has tremen-dous influence on d. The longer the connection exists, the smaller d is, and the advantage of NIOHttpd compared to Httpd is greater. Table 1 and Figure 3 show that NIOHttpd can be 126 times faster than Httpd, given that c=10ms, t=100, s=1MB, and b=8KB/s. NIOHttpd has a big advantage if the connection stays open for a long time. If the con-nection is short, e.g., in a local 100Mb network, the advantage is only 10% provided the files are large. If the files are small, the difference won’t be detectable.
In these calculations it’s assumed that the con-stant costs of NIOHttpd and Httpd are about the same and no new costs are introduced by the differ-ent ways the servers have been implemdiffer-ented. As mentioned before, this comparison only holds under ideal conditions.
This is sufficient, however, to give you the idea that either concept might be beneficial. It should be noted that most Web files are small, but HTTP-1.1-clients try to keep the connection open as long as possible (with a keep-alive or persistent connection). Often, connections that will never again transfer any data are kept open.
In a server with one thread per connection this leads to an incredible waste of resources. So, especially for HTTP servers, the scalability can be increased dramatically by using the new I/O API.
Conclusion
With the new I/O API you can build highly scala-ble servers. In comparison to the old API, it’s a bit more complex and requires a better understanding of multithreading and synchronization. Also, the documentation needs improvement. But if you’ve gotten over these hurdles, the new API proves to be a useful and necessary improvement of the Java 2 platform.
References
• HTTP 1.1: www.w3.org/Protocols/rfc2616/rfc 2616.html
• Lea, D. (1999). Concurrent Programming in Java:
Design Principles and Patterns. Second Edition.
Addison-Wesley. http://gee.cs.oswego.edu/dl/
cpj
A
UTHORB
IOHendrik Schreiber works as senior consultant for innoQ Deutschland GmbH (www.innoq.com) in Ratingen, Germany. His main area of interest is the architecture of modern Java-based solutions using J2EE. He is a coauthor of Java Server and Servlets: Building Portable Web Applications, published by Addison-Wesley.
MAY2002 55
Java COM
Actuate
Corporation
www.actuate.com/info/jbjad.asp
Java COM 56 MAY2002
JDBC 3.0 – Something for Everyone
J D B C 3 . 0
This article describes, in detail, the new features that are available in JDBC 3.0 and explains why they are important.
The JDBC 3.0 specification was shipped as part of the J2SE 1.4 release early in 2002. The key goals of the JDBC Expert Panel were to align with the most important features of SQL99, combine all the previous JDBC specifications into a single document, provide a standard way to take advantage of native DBMS functionality, and improve scalability.
The JDBC 3.0 specification contains a collection of useful new features, none of which, if taken individually, would be considered “major.”