Backend Development 15 min read

Understanding Blocking, Non‑Blocking, I/O Multiplexing, Synchronous and Asynchronous I/O in Java

This article explains the concepts of blocking and non‑blocking I/O, I/O multiplexing mechanisms such as select, poll and epoll, and the differences between synchronous and asynchronous I/O, then demonstrates Java implementations of BIO, NIO and AIO with sample code.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Understanding Blocking, Non‑Blocking, I/O Multiplexing, Synchronous and Asynchronous I/O in Java

The article continues a previous discussion on operating systems and focuses on I/O concepts that are often confused: blocking, non‑blocking, I/O multiplexing, synchronous, asynchronous, BIO, NIO and AIO.

1. Blocking and Non‑Blocking

1.1 Blocking

In blocking I/O, a call to read blocks the user thread until the kernel has prepared the data and copied it from kernel space to user space, after which read returns.

1.2 Non‑Blocking

When a non‑blocking read is issued and data is not ready, the kernel immediately returns an EWOULDBLOCK error. The application must poll the kernel until the data becomes available; the final read that copies data from kernel to user space is still a synchronous operation.

1.3 I/O Multiplexing

I/O multiplexing (select, poll, epoll) allows a single thread to monitor many sockets. The kernel notifies the application when data is ready, eliminating constant polling and improving server throughput.

Select

Select modifies the passed‑in array, can monitor only 1024 descriptors, and is not thread‑safe.

Poll

Poll removes the 1024‑descriptor limit and does not modify the input array, but it is still not thread‑safe.

Epoll

Epoll is thread‑safe, reports the exact socket with ready data, and keeps all descriptors in kernel space, avoiding the overhead of passing them from user space.

2. Synchronous vs Asynchronous I/O

2.1 Synchronous

Synchronous I/O means the data copy from kernel to user space is performed by the user thread. It can be blocking (the thread waits) or non‑blocking (the thread polls).

2.2 Asynchronous

In asynchronous I/O the kernel completes both data preparation and the copy to user space without blocking the calling thread; the kernel notifies the application via a callback when the operation finishes.

3. Java I/O

Java provides three I/O models depending on kernel support:

BIO : Synchronous blocking I/O.

NIO : Synchronous non‑blocking I/O.

AIO : Asynchronous non‑blocking I/O.

3.1 BIO Example

public class Constant {
    public static final String HOST = "127.0.0.1";
    public static final int PORT = 8080;
}
public class ClientMain {
    public static void main(String[] args) {
        System.out.println("开启服务,监听端口:" + Constant.PORT);
        new Thread(new ServerThread()).start();
        System.out.println("客户端,请求连接,并发送数据");
        try {
            Socket socket = new Socket(Constant.HOST, Constant.PORT);
            new Thread(new ClientProcessThread(socket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class ServerThread implements Runnable {
    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(Constant.PORT);
            while (true) {
                Socket socket = serverSocket.accept();
                new Thread(new ServerProcessThread(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class ServerProcessThread implements Runnable {
    private Socket socket;
    public ServerProcessThread(Socket socket) { this.socket = socket; }
    @Override
    public void run() {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            StringBuilder requestStr = new StringBuilder();
            while ((line = bufferedReader.readLine()) != null) {
                requestStr.append(line);
            }
            Writer writer = new OutputStreamWriter(socket.getOutputStream());
            writer.write("data from server " + requestStr + "\r\n");
            writer.flush();
            writer.close();
            bufferedReader.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.2 NIO

NIO uses Selector , Channel and Buffer to achieve non‑blocking I/O. A single thread can manage many channels, reducing thread count and improving resource utilization.

FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
ByteBuffer
CharBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer

Frameworks such as Netty build on NIO to provide high‑performance networking, and RPC frameworks like Dubbo use Netty underneath.

3.3 AIO

AIO (asynchronous I/O) further offloads both data preparation and copying to the kernel, allowing the application to issue an aio_read or aio_write and continue without waiting.

4. References

IO说: https://blog.csdn.net/u013177446/article/details/65936341

爆赞TCP讲解: https://b23.tv/tMxwQV

通俗说IO: https://www.cnblogs.com/LBSer/p/4622749.html

小仙IO: https://t.1yb.co/iEAW

JavanetworkNIOI/Onon-blockingblockingaio
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.