This is the 18th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
This blog is the end of the NIO network programming blog, which explains the concepts of NIO and BIO. The following blog is the end of the NIO network programming blog, explaining the concepts of NIO and BIO.
The Stream and the Channel
-
Streams do not automatically buffer data. Channels take advantage of the send and receive buffers provided by the system (lower level).
-
A stream supports only blocking apis, a channel supports both blocking and non-blocking apis, and a network channel can be multiplexed with selector
-
Both are full-duplex, that is, read and write can be performed at the same time
IO model
Blocking IO
When a user thread performs a read operation, it waits for the operating system to perform the actual read operation, first waiting for the data to arrive over the network and then copying the data. During this time, the user thread is blocked and cannot perform other operations.
Non-blocking IO
-
User threads
The read method is called all the way through a loop, returning immediately if there is no data available in kernel space. However, for non-blocking IO, it is only non-blocking during the wait phase and still blocked during the data replication phase.
-
After discovering data in the kernel space, the user thread waits for the kernel space to replicate the data and returns the result after the replication is complete
multiplexing
In Java, the implementation of multiplex via Selector (see Netty programming (6) — the basic use of Nio. Selector — the gold (juejin. Cn) and Netty programming (7) — nio.Selector read and write events – Nuggets (juejin. Cn)
- When there is no event, calling the SELECT method is blocked
- Once one or more events occur, the corresponding events will be processed to achieve multiplexing
Difference between multiplexing and blocking IO
Here’s the difference between multiplexing and blocking IO
- In blocking I/O mode, if the thread is blocked due to accept, it still needs to wait for the accept to complete before processing the READ event. This is the biggest problem with BLOCKING I/O
- In multiplexing mode, the execution of an event is not affected if another event is blocked after the event occurs
Asynchronous I/o
Asynchronous IO is when thread 1 calls a method and understands its return. It does not block and does not need to get the result immediately. When the result of the method is available, thread 2 returns the result to thread 1.
AIO
AIO is the asynchronous IO mentioned above, which is used to solve the blocking problem in the data replication phase
- Synchronization means that while reading or writing, the thread waits for the result, or is essentially idle
- Asynchronous means that while reading or writing, the thread does not have to wait for the result, but that the operating system will get the result from another thread in the future through callbacks
Here is an example of reading file contents asynchronously:
@Slf4j
public class TestAIO {
public static void main(String[] args) throws IOException {
AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("data2.txt"), StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(16);
log.debug("read begin...");
channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override / / read success
public void completed(Integer result, ByteBuffer attachment) {
log.debug("read complete... {}",result);
attachment.flip();
ByteBufferUtil.debugAll(buffer);
}
@Override / / read failure
public void failed(Throwable exc, ByteBuffer attachment) {}}); log.debug("read end..."); System.in.read(); }}Copy the code
The result is as follows, and you can see that reading and printing the result is indeed done asynchronously