← Back to Advanced Java Course | Chapter 13: Java NIO | Lesson 5 of 5

Java Non-blocking Sockets

NIO's SocketChannel and ServerSocketChannel support non-blocking network I/O, letting a single thread with a Selector manage many concurrent client connections at once.

Blocking vs Non-blocking Sockets

A classic java.net.Socket blocks the calling thread while waiting for data, requiring one dedicated thread per connection, while NIO's SocketChannel can be switched into non-blocking mode, letting one thread service many connections.

Example: Blocking vs Non-blocking Sockets

java
import java.nio.channels.SocketChannel;
public class Main {
	public static void main(String[] args) throws Exception {
		SocketChannel channel = SocketChannel.open();
		channel.configureBlocking(false); // one thread can service many such channels
		System.out.println("Non-blocking: " + !channel.isBlocking());
		channel.close();
	}
}

Opening a ServerSocketChannel

ServerSocketChannel is the NIO equivalent of ServerSocket, accepting incoming connections but capable of doing so non-blockingly when registered with a Selector.

Example: Opening a ServerSocketChannel

java
import java.nio.channels.ServerSocketChannel;
public class Main {
	public static void main(String[] args) throws Exception {
		ServerSocketChannel server = ServerSocketChannel.open();
		server.bind(new java.net.InetSocketAddress(0));
		server.configureBlocking(false); // can accept non-blockingly when registered with a Selector
		System.out.println("Listening on port " + server.socket().getLocalPort());
		server.close();
	}
}

Registering Channels with a Selector

A non-blocking channel is registered with a Selector for a specific interest, such as OP_ACCEPT or OP_READ, and the Selector reports back only the channels that are actually ready for that operation.

Example: Registering Channels with a Selector

java
import java.nio.channels.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Selector selector = Selector.open();
		ServerSocketChannel server = ServerSocketChannel.open();
		server.bind(new java.net.InetSocketAddress(0));
		server.configureBlocking(false);
		server.register(selector, SelectionKey.OP_ACCEPT); // interested in accept events only
		System.out.println("Registered for OP_ACCEPT");
		selector.close();
		server.close();
	}
}

The Selector Event Loop

A Selector-based server runs a loop calling select(), which blocks until at least one registered channel is ready, then iterates the ready set to handle each event, such as accepting a connection or reading available data.

Example: The Selector Event Loop

java
import java.nio.channels.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Selector selector = Selector.open();
		ServerSocketChannel server = ServerSocketChannel.open();
		server.bind(new java.net.InetSocketAddress(0));
		server.configureBlocking(false);
		server.register(selector, SelectionKey.OP_ACCEPT);
		int ready = selector.selectNow(); // non-blocking check instead of select() for this demo
		System.out.println("Ready channels: " + ready);
		selector.close();
		server.close();
	}
}

Accepting and Reading Client Connections

Inside the event loop, an OP_ACCEPT-ready key means a new client can be accepted, while an OP_READ-ready key means an already-connected client has data waiting to be read into a buffer.

Example: Accepting and Reading Client Connections

java
import java.nio.channels.*;
import java.net.InetSocketAddress;
public class Main {
	public static void main(String[] args) throws Exception {
		ServerSocketChannel server = ServerSocketChannel.open();
		server.bind(new InetSocketAddress(0));
		server.configureBlocking(false);
		// OP_ACCEPT-ready key -> server.accept() returns a new client SocketChannel
		// OP_READ-ready key -> that client channel has data waiting in a buffer
		System.out.println("Server ready to accept on port " + server.socket().getLocalPort());
		server.close();
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Registering a channel with a Selector without calling configureBlocking(false), which throws an IllegalBlockingModeException.
  2. Not removing the key from selectedKeys() after handling it, so the same event is processed again on the next loop.
  3. Assuming one read returns a full message, when a non-blocking read may return only part of the data or 0 bytes.
Chapter Summary
  • Java NIO offers non-blocking I/O as an alternative to the classic I/O streams.
  • The Path and Files API, async file I/O, and WatchService handle files and directory changes.
  • Non-blocking sockets extend the same approach to network communication.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.