Java Non-Blocking I/O Concepts: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 5: Line 5:
=Overview=
=Overview=


Until NIO, all that was available for I/O in Java were Streams (<tt>java.io.*</tt>). All operations with Streams are blocking: a thread waits until there is data to read from the Stream instance or until it can write to the Stream instance. The disadvantage of this approach is that multiple threads are required when we need to simultaneously handle multiple sources of data, such as concurrent network connections. These threads usually spend most of their time blocked waiting on I/O events. This is the I/O and threading model Tomcat is built on.  
Until NIO, all that was available for I/O in Java were Streams (<tt>java.io.*</tt>). All operations with Streams are blocking: a thread waits until there is data to read from the Stream instance or until it can write to the Stream instance. The disadvantage of this approach is that multiple threads are required when we need to simultaneously handle multiple sources of data, such as concurrent network connections. These threads usually spend most of their time blocked waiting on I/O events. This is the I/O and threading model Tomcat is built on. Another particularity of the Stream API is that it reads or writes data one byte at a time, which is not the most efficient way of doing I/O - the O/S handle I/O in block.
 
NIO addresses both of this problems: it offers





Revision as of 22:05, 25 July 2018

Internal

Overview

Until NIO, all that was available for I/O in Java were Streams (java.io.*). All operations with Streams are blocking: a thread waits until there is data to read from the Stream instance or until it can write to the Stream instance. The disadvantage of this approach is that multiple threads are required when we need to simultaneously handle multiple sources of data, such as concurrent network connections. These threads usually spend most of their time blocked waiting on I/O events. This is the I/O and threading model Tomcat is built on. Another particularity of the Stream API is that it reads or writes data one byte at a time, which is not the most efficient way of doing I/O - the O/S handle I/O in block.

NIO addresses both of this problems: it offers


NIO (java.nio.*) offers access to underlying O/S non-blocking I/O facilities and offers a selectors mechanism through which a single thread could be notified and process I/O events arriving from multiple sources.

Also, because the underlying operating system I/O facilities are block-oriented for efficiency - hardware usually transfers data in blocks rather than byte by byte - NIO exposes block-level access via Channels and Buffers. Data can be read and written in blocks via Buffers into and from Channels. Streams only offer sequential access - once a byte has been read, it is gone from the Stream and it is the application's responsibility to cache it locally if it needs it later. With Buffer, the caching is already done, efficiently, by the O/S.

Channels are also sources of asynchronous I/O events that are routed by selectors into the application. The data transfer between Channels and Buffers is done transparently, without requiring application threads to move bytes around. An application thread is notified once the transfer had completed via an I/O event. The NIO API does not do anything that the Stream API can't do - essentially reading and writing data from/to I/O devices - but it does it faster and using less threads.

Block-access and non-blocking I/O read and write allow Java applications to implement high-speed I/O without having to write native code that would access O/S specific facilities.

Primitives

Selector

Selector

A multiplexor that allows registration of multiple selectable channels so they can be serviced by a single selector thread. The selector thread will block in select() and it will be notified by the selector's implementation only when an I/O event, such as data becoming available or a new connection being established, occurs.

Channel

Selectable channel.

ServerSocketChannel

ServerSocketChannel

A selectable channel used to listen for incoming network connections and create new SocketChannels for each TCP connection. The ServerSocketChannel delegates to a ServerSocket to do the actual listening.

SocketChannel

SocketChannel

Buffer

Java NIO and TCP Connections

A working example that shows various Java NIO primitives collaborating in establishing a bidirectional TCP connection:

Java NIO and TCP Connections