Five ways to maximize Java NIO and NIO.2--reference
Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purpose was to improve the programming of I/O-intensive chores on the Java platform. A decade later,many Java programmers still don't know how to make the best use of NIO,and even fewer are aware that Java SE 7 introduced More New Input/Output APIs (NIO.2). In this tutorial you'll find five easy examples that demonstrate the advantages of the NIO and NIO.2 packages in common Java programming scenarios. The primary contribution of NIO and NIO.2 to the Java platform is to improve performance in one of the core areas of Java application development: input/output processing. Neither package is particularly easy to work with,nor are the New Input/Output APIs required for every Java I/O scenario. Used correctly,though,Java NIO and NIO.2 can slash the time required for some common I/O operations. That's the superpower of NIO and NIO.2,and this article presents five relatively simple ways to leverage it: The NIO contextHow is it that a 10-year-old enhancement is still the?New?Input/Output package for Java? The reason is that for many working Java programmers the basic Java I/O operations are more than adequate. Most Java developers don't?have?to learn NIO for our daily work. Moreover,NIO isn't just a performance package. Instead,it's a heterogeneous collection of?facilities related to Java I/O. NIO boosts Java application performance by getting "closer to the metal" of a Java program,meaning that the NIO and NIO.2 APIs expose lower-level-system operating-system (OS) entry points. The tradeoff of NIO is that it simultaneously gives us greater control over I/O and demands that we exercise more care than we would with basic I/O programming. Another aspect of NIO is its attention to application expressivity,which we'll play with in some of the exercises that follow. For many developers the first encounter with NIO might happen during maintenance work: an application has correct functionality but is slow to respond,so someone suggests using NIO to accelerate it. NIO shines when it's used to boost processing performance,but its results will be closely tied to the underlying platform. (Note that NIO is platform dependent.) If you're using NIO for the first time,it will pay you to measure carefully. You might discover that NIO's ability to accelerate application performance depends not only on the OS,but on the specific JVM,host virtualization context,mass storage characteristics,and even data. Measurement can be tricky to generalize,however. Keep this in mind particularly if a mobile deployment is among your targets. And now,without further ado,let's explore five important facilities of NIO and NIO.2. 1. Change notifiers (because everybody needs a listener)Java application performance is the common draw for developers interested in NIO or NIO.2. In my experience,however,NIO.2's file change notifier is the most compelling (if under-sung) feature of the New Input/Output APIs. Many enterprise-class applications need to take a specific action when:
These are all examples of change notification or change response. In early versions of Java (and other languages),?polling?was typically the best way to detect change events. Polling is a particular kind of endless loop: check the file-system or other object,compare it to its last-known state,and,if there's no change,check back again after a brief interval,such as a hundred milliseconds or ten seconds. Continue the loop indefinitely. NIO.2 gives us a better way to express change detection. Listing 1 is a simple example. Listing 1. Change notification in NIO.2 java.nio.file.attribute.* java.io.* java.util.*<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> Watcher {
<span style="color: #0000ff;">public <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> main(String[] args) { Path this_dir = Paths.get("."<span style="color: #000000;">); System.out.println("Now watching the current directory ..."<span style="color: #000000;">);
} Compile this source,then launch the command-line executable. In the same directory,create a new file; you might,for example,?
This simple example illustrates how to begin accessing NIO's language facilities in Java. It also introduces NIO.2's? TipNIO's notifiers are so much easier to use than the polling loops of old that it's tempting to neglect requirements analysis. But you should think through these semantics the first time you use a listener. Knowing when a file modification?ends?is more useful than knowing when it begins,for instance. That kind of analysis takes some care,especially in a common case like the FTP drop folder. NIO is a powerful package with some subtle "gotcha's"; it can punish a casual visitor. 2. Selectors and asynchronous I/O: Selectors help multiplexNewcomers to NIO sometimes associate it with "non-blocking input/output." NIO is more than non-blocking I/O but the error makes sense: basic I/O in Java is?blocking?-- meaning that it waits until it can complete an operation -- whereas non-blocking,or asynchronous,I/O is one of the most-used NIO facilities. NIO's non-blocking I/O is?event-based,as demonstrated by the file-system listener in Listing 1. This means that a?selector?(or callback or listener) is defined for an I/O channel,then processing continues. When an event occurs on the selector -- when a line of input arrives,for instance -- the selector "wakes up" and executes. All of this is achieved?within a single thread,which is a significant contrast to typical Java I/O. Listing 2 demonstrates the use of NIO selectors in a multi-port networking echo-er,a program slightly modified from one created by Greg Travis in 2003 (see?). Unix and Unix-like operating systems have long had efficient implementations of selectors,so this sort of networking program is a model of good performance for a Java-coded networking program. Listing 2. NIO selectors java.io.* java.net.* java.nio.* java.nio.channels.* java.util.*<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> MultiPortEcho
{ <span style="color: #0000ff;">private <span style="color: #0000ff;">int<span style="color: #000000;"> ports[]; <span style="color: #0000ff;">private ByteBuffer echoBuffer = ByteBuffer.allocate( 1024<span style="color: #000000;"> );
} Compile this source,then launch it from the command-line with an invocation such as? 3. Channels: Promise and realityIn NIO,a?channel?can be any object that reads or writes. Its job is to abstract files and sockets. NIO channels support a consistent collection of methods,so it's possible to program without having special cases depending on whether? While NIO is often promoted for its performance advantages,it's more precise to say it is highly?responsive. In some cases NIO actually performs?worse?than basic Java I/O. For simple sequential reads and writes of small files,for instance,a straightforward streams implementation might be two or three times faster than the corresponding event-oriented channel-based coding. Also,?non-multiplexed channels -- that is,channels in separate threads -- can be much slower than channels that register their selectors in a single thread. The next time you need to define a programming problem in terms of dimensions pertinent to streams or channels,try asking the following questions:
This sort of analysis is good practice for deciding when to use streams or channels. Remember: NIO and NIO.2 don't replace basic I/O; they just supplement it. 4. Memory mapping -- where it countsThe most consistently dramatic performance improvement in the use of NIO involves memory mapping.?Memory mapping?is an OS-level service that makes segments of a file appear for programming purposes like areas of memory. Memory mapping has a number of consequences and implications,more than I'll get into here. At a high level,it helps make I/O happen at the speed of memory access,rather than file access. The former is often two orders of magnitude faster than the latter. Listing 3 is a minimal demonstration of NIO's memory-mapping facility. Listing 3. Memory mapping in NIO</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> mem_map_example {
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> mem_map_size = 20 * 1024 * 1024<span style="color: #000000;">;
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> String fn = "example_memory_mapped_file.txt"<span style="color: #000000;">;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception {
RandomAccessFile memoryMappedFile </span>= <span style="color: #0000ff;">new</span> RandomAccessFile(fn,"rw"<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;">Mapping a file into memory</span>
MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE,0<span style="color: #000000;">,mem_map_size);
</span><span style="color: #008000;">//</span><span style="color: #008000;">Writing into Memory Mapped File</span>
<span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < mem_map_size; i++<span style="color: #000000;">) {
out.put((</span><span style="color: #0000ff;">byte</span>) 'A'<span style="color: #000000;">);
}
System.out.println(</span>"File '" + fn + "' is now " + Integer.toString(mem_map_size) + " bytes full."<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Read from memory-mapped file.</span>
<span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 30 ; i++<span style="color: #000000;">) {
System.out.print((</span><span style="color: #0000ff;">char</span><span style="color: #000000;">) out.get(i));
}
System.out.println(</span>"nReading from memory-mapped file '" + fn + "' is complete."<span style="color: #000000;">);
}
} The small model in Listing 3 quickly creates a 20-megabyte file,? 5. Character encoding and searchingThe final feature of NIO that I want to introduce in this article is? Listing 4 shows an example of a conversion from Java's native Unicode character encoding to Latin-1. Listing 4. Character encoding in NIONote that? Conclusion: Of course there's moreThe purpose of this article has been to familiarize working Java developers with some of the main (and most useful) facilities of NIO and NIO.2. You can use the foundation established by the examples here to understand some of NIO's secondary methods; for instance,what you've learned about channels will help you make sense of NIO's? reference from: http://www.javaworld.com/article/2078654/java-se/five-ways-to-maximize-java-nio-and-nio-2.html http://www.javaworld.com/article/2078654/java-se/five-ways-to-maximize-java-nio-and-nio-2.html?page=2 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |