BIO means Blocking IO.
A classic example of BIO is that an application requests network IO operations from the operating system, and the application will wait all the time.
On the other hand, the operating system will also wait until there is data on the network.
When data is transmitted to the listening port, the operating system collects the data and will send the data to the application.
Finally the application receives the data and releases the waiting state.
What You Need
- About 4 minutes
- A favorite text editor or IDE
- Java 8 or later
Traditional BIO Communication
Most network communication methods used to be blocking mode :
- After the client sends a request to the server, the client will wait (and will not do anything else) until the server returns the result or there is a problem with the network;
- Similarly on the server side, when processing a request from a client A, the request from another client B will wait until the server completes the previous processing.

Problems of traditional BIO network communication
- At the same time, the server can only accept the request from client A although the requests from client A and client B are carried out at the same time, the request sent by client B can only wait until the server finish with the request of client A;
- Since the server can only process one client request at a time, obviously, such a processing method cannot be used in the case of high concurrency.
Traditional BIO Communication In Multi-Thread Mode
The situation mentioned above is that the server has only one thread, we can use multi-threading technology to solve this problem :
- When the server receives the request of client A, it sends the request to a separate thread for processing, and then the main thread continues to accept the request of client B;
- On the client side, a child thread can also be used to communicate with the server side. In this way, other work of the client’s main thread will not be affected. When the server returns response, the child thread will notify the main thread through the listening/observation mode.

Below is an example of two clients sending simultaneously requests to server implementing BIO multi-thread mode :
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
public class BIO {
public static void main(String[] args) throws InterruptedException {
final int port = 3000;
Runnable server = () -> {
try (ServerSocket ss = new ServerSocket(port)) {
while (true) {
Socket accept = ss.accept();
Runnable handler = () -> {
handleRequest(accept);
};
new Thread(handler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
};
new Thread(server).start();
TimeUnit.SECONDS.sleep(3);
Runnable clientA = () -> {
sendRequest(port, "A", "hello world");
};
new Thread(clientA).start();
Runnable clientB = () -> {
sendRequest(port, "B", "world hello");
};
new Thread(clientB).start();
}
private static void handleRequest(Socket accept) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()))) {
StringWriter writer = new StringWriter();
String line;
while ((line = br.readLine()) != null) {
writer.write(line);
}
String request = writer.toString();
System.out.println(
"request '" + request + "' has been handled by server's thread " + Thread.currentThread().getId());
} catch (IOException e) {
e.printStackTrace();
}
}
private static void sendRequest(final int port, String client, String request) {
try (Socket s = new Socket("localhost", port)) {
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()))) {
bw.write(request);
System.out.println(
"request '" + request + "' has been sent to server by client " + client + "'s thread "
+ Thread.currentThread().getId());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The output of above code snippet is below :
request 'hello world' has been sent to server by client A's thread 20
request 'world hello' has been sent to server by client B's thread 21
request 'hello world' has been handled by server's thread 23
request 'world hello' has been handled by server's thread 24
But using multi-threads to solve this problem actually is not a good solution :
- Although on the server side, the processing of the request is handed over to a separate thread, the acceptance of data packets still needs to be done one by one;
- Threads that can be created are limited in no matter what operating system, the more threads, the longer it takes to switch CPUs, and the less it handles real business;
- Creating a thread is resource-intensive. When the JVM creates a thread, even if the thread does not do any work, the JVM has to allocate a stack for the thread;
- If the application uses a lot of long connections, the thread will not be closed. In this way, the consumption of system resources is more likely to get out of control.