|
|
|
Send this page as an email |
|
|
Level: elementary Aruna kalagnanam, software engineer, IBM Balu g (gbalu@in.ibm.com), software engineer, IBM March 12, 2002
The Java technology platform should have provided non-blocking I/O mechanisms for a long time. Fortunately, Merlin (JDK 1.4) has a magic wand that applies in almost every scenario, and the blocking state of the blocked I/O is exactly what the magician is doing. Software engineers Aruna kalagnanam and Balu g introduced Merlin's new I/O package-java. niO (NIO)-This non-blocking feature, and uses a socket programming example to show you what NiO can do. ClickDiscussionTo share your experiences with the author and other readers in the Forum.
The server's ability to process a large number of client requests within a reasonable period of time depends on the efficiency of the server's use of the I/O Stream. At the same time, servers that provide services to hundreds of clients must be able to concurrently use the I/O service. The Java platform does not support non-blocking I/O calls until JDK 1.4 (Merlin. For a server written in Java, the ratio of the thread to the client is almost the same, which is vulnerable to a large number of thread overhead. The result is that both performance problems and scalability are caused. To solve this problem, the latest release of the Java platform introduces a new group of classes. Merlin's Java. Nio package is full of skills to solve thread overhead problems. The most important thing in the package is the newSelectableChannel Class andSelector Class.Channel)It is a communication method between the client and the server.Selector)Similar to Windows message loop, it captures various events from different clients and distributes them to corresponding event handlers. In this article, we will show you how these two classes work together to create a non-blocking I/O Mechanism for the Java platform. I/O programming before Merlin We will start from the basic server-socket (server-socket) program before Merlin. InServerSocket Important Functions of the class are as follows:
- Accept incoming connections
- Read requests from clients
- Provide services for requests
Let's take a look at each of the above steps. We use code snippets to describe them. First, we create a newServerSocket :
ServerSocket s = new ServerSocket(); |
Next, we need to accept incoming calls. Here, callaccept() You should be able to complete the task, but there is a small trap:
Socket conn = s.accept( ); |
Pairaccept() Until the server socket accepts a client request for connection. Once a connection is established, the server usesLineNumberReader Read client requests. BecauseLineNumberReader Data is read in batches only when the buffer is full, so this call is blocked during reading. The following snippet showsLineNumberReader (Blocking, etc ).
InputStream in = conn.getInputStream();InputStreamReader rdr = new InputStreamReader(in);LineNumberReader lnr = new LineNumberReader(rdr);Request req = new Request();while (!req.isComplete() ){ String s = lnr.readLine(); req.addLine(s);} |
InputStream.read() Is another way to read data. Unfortunately,read The method must be blocked until the data is available,write The same is true ,.
Figure 1 depicts a typical server process. A black line indicates a blocking operation. Figure 1. Typical servers at work
Before JDK 1.4, free use of threads is the most typical way to handle blocking problems. However, this solution produces its own problem-thread overhead, which affects both performance and scalability. However, with the advent of Merlin and Java. Nio packages, everything has changed. In the following sections, we will examine the basic idea of Java. NiO, and then apply some of the knowledge we have learned to modify the server-socket example described above.
Reactor Pattern) The foundation of NiO design is the design mode of reactors. Server Applications in distributed systems must process multiple clients that send service requests to them. However, before calling a specific service, the server application must allocate and distribute each incoming request to the corresponding service provider. The reactor mode is suitable for this function. It allows event-driven applications to distribute and distribute service requests concurrently from one or more clients to the application.
|
Core functions of the reactor model
- Multiplexing of events
- Distribute events to corresponding event handlers
|
|
The reactor pattern is very similar to the observer pattern in this respect: When a subject changes, all dependent bodies are notified. However, the observer mode is associated with a single event source, while the reactor mode is associated with multiple event sources. See references for more information about the reactor mode.
Channels and selectors NIO's non-blocking I/O mechanism is centered aroundSelectorAndChannelBuilt.Channel Class indicates a communication mechanism between the server and the client. Consistent with the reactor mode,Selector Class isChannel .Selector Class is used to distribute incoming client requests to multiple channels and distribute them to their respective request handlers. We will take a closer lookChannel Class andSelector And how the two classes work together to create non-blocking I/O implementations. What do channels do? A channel represents a connection to an object (for example, a hardware device, file, network socket, or program component that can perform one or more different I/O operations (for example, read or write). The NiO channel can be closed and interrupted asynchronously. Therefore, if a thread blocks the I/O operations of a channel, the other thread can close the channel. Similarly, if a thread is blocked in the I/O operation of a channel, the other thread can interrupt the blocking thread. Figure 2. java. NiO. Channels class hierarchy
As shown in figure 2, there are many Channel interfaces in the Java. NiO. Channels package. We are mainly concerned aboutjava.nio.channels.SocketChannel Interfaces andjava.nio.channels.ServerSocketChannel Interface. These two interfaces can be used to replacejava.net.Socket Andjava.net.ServerSocket . Although we will certainly focus on using channels in a non-blocking manner, the channel can be used in blocking or non-blocking mode. Create a non-blocking Channel To implement basic non-blocking Socket read and write operations, we need to process two new classes. They are from the java.net package.InetSocketAddress Class, which specifies the connection location and from the java. NiO. Channels packageSocketChannel Class, which performs the actual read and write operations. The code snippets in this section show a modified, non-blocking method to create a basic server-socket program. Note the changes between these code samples and the code used in the first example, starting with adding two new classes:
String host = ......; InetSocketAddress socketAddress = new InetSocketAddress(host, 80);SocketChannel channel = SocketChannel.open(); channel.connect(socketAddress); |
|
Buffer role Buffer Is an abstract class that contains specific basic data types. Essentially, it is a package that wraps an array of fixed sizes with the getter/setter method. These getter/setter methods allow access to the buffer content.Buffer The class has many subclasses, as shown below:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
ByteBuffer Is the only class that supports reading and writing other types, because other classes are specific to types. Once connected, you can useByteBuffer The object reads data from or writes data to the channel. For more information, see references.ByteBuffer .
|
|
To make the channel non-blocking, we callconfigureBlockingMethod(false) , As shown below:
channel.configureBlockingMethod(false); |
In blocking mode, the thread blocks reading or writing until the read or write operations are complete. If the data has not completely reached the socket at the time of reading, the thread will block the reading operation until the data is available. In non-blocking mode, the thread reads available data (no matter how much) and then returns to execute other tasks. If true is passedconfigureBlockingMethod() InSocket The behavior for blocking reading or writing is the same. The only major difference is that these blocked reads and writes can be interrupted by other threads. IndependentChannel Creating non-blocking I/O implementations is not enough. To implement non-blocking I/O,Channel The class must beSelector Class. What do selector do? In the reactor mode,Selector ClassReactor Role.Selector For multipleSelectableChannels . EachChannel DirectionSelector Register an event. When the event arrives from the client,Selector Multiple channels are used to distribute these events to the correspondingChannel . CreateSelector The simplest way is to useopen() Method:
Selector selector = Selector.open(); |
Channel encounter Selector EachChannel You must first create a connection. The following code is calledServer OfServerSocketChannel And bind it to the local port:
ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);InetAddress ia = InetAddress.getLocalHost();InetSocketAddress isa = new InetSocketAddress(ia, port );serverChannel.socket().bind(isa); |
EachChannel You must continueSelector Register.Channel The event to be handled should be registered based on it. For exampleChannel You should register as follows:
SelectionKey acceptKey = channel.register( selector,SelectionKey.OP_ACCEPT); |
Channel DirectionSelector For registrationSelectionKey Object Representation. Meet one of the following three conditions,Key It becomes invalid:
Channel Disabled.
Selector Disabled.
- By calling
Key Ofcancel() MethodKey Canceled.
Selector Inselect() The call is blocked. Then, it starts to wait until a new connection is established, or another thread wakes it up, or another thread interrupts the original blocked thread.
Registration Server Server IsSelector Register to accept all incoming connectionsServerSocketChannel , As shown below:
SelectionKey acceptKey = serverChannel.register(sel, SelectionKey.OP_ACCEPT); while (acceptKey.selector().select() > 0 ){ ...... |
Server After registration, a set of keywords are processed iteratively based on the type of each key. After a keyword is processed, it is removed from the ready keys list, as shown below:
Set readyKeys = sel.selectedKeys(); Iterator it = readyKeys.iterator();while (it.hasNext()) {SelectionKey key = (SelectionKey)it.next(); it.remove(); .... .... .... } |
If the keyword is acceptable (acceptable), accept the connection and register the channel to accept more events (for example, read or write operations ). If the keyword is readable or writable, the server instructs you that it is ready to read and write local data:
SocketChannel socket;if (key.isAcceptable()) { System.out.println("Acceptable Key"); ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); socket = (SocketChannel) ssc.accept(); socket.configureBlocking(false); SelectionKey another = socket.register(sel,SelectionKey.OP_READ|SelectionKey.OP_WRITE);}if (key.isReadable()) { System.out.println("Readable Key"); String ret = readMessage(key); if (ret.length() > 0) { writeMessage(socket,ret); } }if (key.isWritable()) { System.out.println("Writable Key"); String ret = readMessage(key); socket = (SocketChannel)key.channel(); if (result.length() > 0 ) { writeMessage(socket,ret); } } |
Why? alimail-non-blocking server socket is quick! The last part of the introduction to non-blocking I/O in JDK 1.4 is left to you: Run this example. In this simple non-blocking server-socket example, the server reads the file name sent from the client, displays the content of the file, and then writes the content back to the client. Here is what you need to do to run this example:
- Install JDK 1.4 (see references ).
- Copy two source code files to your directory.
- Compile and run the server,
java NonBlockingServer .
- Compile and run the client,
java Client .
- Enter the name of a text file or Java file in the directory where the class file is located.
- The server will read the file and send its content to the client.
- The client prints the data received from the server. (Because
ByteBuffer So only 1024 bytes are read .)
- Enter the quit or shutdown command to close the client.
Conclusion Merlin's new I/O package covers a wide range. Merlin's new non-blocking I/O implementation has two main advantages: the thread is no longer blocked during reading or writing, andSelector It can process multiple connections, greatly reducing the overhead of server applications. We have already focused on the two advantages of the new java. Nio package. We hope that you will apply the knowledge learned here to your actual application development work. References
- For more information, see the original article on the developerworks global site.
- ClickDiscussionParticipate in this forum.
- Download the source code and run the example in this article.
- Install JDK 1.4.
- Learn about all new non-blocking I/O APIs on the NIO homepage.
- For more information about JDK 1.4, see Java 2 platform, Standard Edition, and v1.4 overview.
- Visit Java Community process to learn about the process of Java. Nio package becoming part of the Java platform.
- For more information about the long-standing thread overhead of the Java platform, see proposal for fixing the Java platform's threading problems of Allen Holub, some of them discuss Java I/O (Developerworks, January 1, October 2000 ).
- Learn more about the bytebuffer class.
- Obtain more information about reactor pattern.
- John zukoski'sMagic with MerlinThe column describes the changes that Merlin brings to the Java platform.
- Javaworld"Master Merlin's new I/O classes" tells you how to obtain the maximum performance from the non-blocking I/O and memory ing buffers.
- Would you like to explore the options for a developer? Please referDeveloperworksFrom the full list of IBM.
- You canDeveloperworksIn the Java technology area, I found hundreds of articles on various aspects of Java programming.
Author Profile
|
|
|
Aruna kalagnanam is a software engineer for IBM India lab e-commerce integration technology. You can contact Aruna through the kaaruna@in.ibm.com. |
|
|
|
Balu G is a software engineer for IBM India lab e-commerce integration technology. You can contact Balu via gbalu@in.ibm.com. |
|