preface
Java was born so far, from the early Java IO model to Java NIO to the latest Java AIO. Java IO development up to now, there are dozens of related operation classes, they together constitute a perfect Java IO functional system. Small to our daily reading of files, big to the game server development are involved, because recently in learning Netty, and Netty is based on Java NIO development of a high-performance network framework, in the process of learning it is inevitable to re-examine some content about Java IO, take this opportunity, Summarize the common IO models. This article is only a macro explanation of the operation mechanism of several different IO models. If you are interested in the internal actual code details, you can check the information and learn privately. My own words, at most to write a decorative design pattern in Java IO application bar, after all, their own food, other dare not disorderly write.
First of all, I is input O is ouput this point has not needed my more statement, do not know back to reflect. IO operations is essentially to the operation of the memory, through IO operations we can realize the exchange of data, such as read from the hard disk data, with the keyboard typing, etc., although Java provides the flow operation characters this concept, but in the system, the underlying IO operations still took the form of byte stream transmission and processing, the emergence of the characters of the flow simplifies operation on a lot of coding. Before introducing the specific IO model, let’s take a look at the basic concepts of input and output streams, as follows:
- When I/O, data flows over a communication channel. The so-called “stream” refers to the starting point and ending point of all data communication channels. The channel of information is a data stream. Any channel through which data flows from one place to another is called a data flow.
- Input/output is relative to the program. Programs play two roles in using data: one as source and one as destination. When a program is the source, or provider, of a data flow, the data flow is an “output data flow” to the program (data flows out of the program). If the program is the endpoint of a data flow, the data flow to the program is an “input data flow” (data flowing from the program to the program)
IO model
Common IO models are mainly divided into the following five types, including synchronous IO we hear more, blocking IO are included in these five categories, they are respectively:
- Block type IO
- Non-blocking IO
- Asynchronous I/o
- Signal driven IO
- Multiplexing IO
Block type IO
First of all, let’s understand the meaning of the word “obstruction”. The so-called “obstruction” in the dictionary means that there is an obstacle that cannot be passed. For example, if you are driving in a traffic jam, the car in front of you is an obstacle to your progress. My personal understanding of blocking in our programming is as follows:
The execution of an operation depends on the result of the previous operation
This dependence is very serious, like a couple in love, without who can not live. Our common printer, for example, when a printer is printing, another thread to request the printer, there is no way to ask the printer to swallow printing paper back and print, this thread is the only can do is waiting for the printer to print the current task, return OK state to IO thread, IO thread can request execution printer to print. Similarly, requests to manipulate files that are being processed by another IO thread will block until the file is processed by the current thread.
Here to understand the nature of the blocking IO this concept will find it is insufficient, although in the execution sequence block type IO error probability is very small, but as a result of the existence of blocking, especially when an IO thread obstruction in a long time, will be very affect the efficiency of the system, at the same time thread creation and destruction, switch, Waiting for actions and so on costs the operating system time and resources and can lead to performance degradation problems for our programs.
Non-blocking IO
The big difference between non-blocking IO and blocking IO is that non-blocking IO doesn’t wait around like blocking IO does, but every once in a while goes to see if the thread you’re working on is done, and then it’s my turn. For reading data operation, of course, the whole process is still blocked, but because of the increased check this link, it is not entirely call blocking, because in the process of waiting for data, which in addition to wait, it can also do something else, of course, also can do the checking, but because it will go to check whether there is data in a while, So it can’t do much, because in the actual operation, non-blocking IO does not bring significant performance improvement over blocking IO, nor does it solve the fatal problem of blocking IO, so in the actual development of the use of less.
Multiplexing IO
At this point, many people have a question, since blocking IO and non-blocking IO have such obvious disadvantages, don’t the industry provide corresponding solutions?
The answer, of course, is multiplexing and signal-driven IO. Signal-driven IO will be covered below. Let’s look specifically at multiplexing IO.
In my personal understanding, multiplexing can be understood as multiple threads, while reuse is reuse. So what exactly does multiplexing IO implement? Limited by the architecture of our operating system, no matter how much SAO operation can not achieve multiple threads to read without waiting, so scientists cleverly came up with such A way, I open another thread, let’s call it thread A, and another thread we call thread B. Which leads to the following conversation:
Thread B came to file MISS C’s door, found file miss C’s door locked from the inside, but also hung a sign saying that there is an indescribable &(&)%$&, thread B saw that he could not get in, so he thought he could only wait. At this point, thread A appears.
Thread A: How silly of you to keep waiting. I’m Miss File C’s assistant, by the way. Tell you what, here’s your number, #008000, “he said, handing thread B a green sign. Then you do what you have to do, and I’ll call you when our lady is done.
Thread B: It feels weird, but thank you. I’m going to go home and play video games.
Analyzing the execution process, we found that with the existence of thread A, thread B does not have to constantly check whether there is data, but can rest assured to do their own things. In essence, we can understand multiplexing IO as an enhanced version of non-blocking IO, its advantage is that it can handle a large number of IO requests, with a thread to manage all THE IO requests, without blocking IO and non-blocking IO, each IO needs a thread to process, improving the throughput of the system.
Signal driven IO
Signal-driven I/O means that the process notifies the kernel in advance so that when an event occurs on a descriptor, the kernel uses a signal to notify the relevant process.
The concept is a little hard to understand, but suddenly I found that the example above is quite vivid, HHHH, unfortunately, I didn’t think of it at the beginning of the writing, you can imagine.
Two days later, Thread B reappeared at Miss File C’s door, which was still closed with the familiar sign.
Thread B looked around and saw that thread A was nowhere to be found. While Thread A was looking for it, A notice next to the door caught thread A’s attention:
Hello everyone, I am A thread A, now told the broad masses of customers, my friends, because before the work is too boring, but also earn less, so I called the A north green bear programming training, I now learn to return, for the file C miss developed automatic guest management notification system, specific operation as follows, scan the qr code below. Attention marson public, Register and become our customer, click on the appointment, miss C file available the system will notify you.
Thread A: Fuck, this is soft.
Of course, the actual situation, signal driven IO is not much, because signal driven IO is the use of SIGIO signal, because TCP protocol in the process of data transmission will produce a large number of SIGIO signals, so generally used in UDP more.
Asynchronous I/o
Several IO models in front of nature, or belong to the category of synchronous IO because even multiplexing IO and signal drive IO can solve the problem of blocking type of IO, but not all of the whole process is blocked, there are still blocked link, and the asynchronous I/o its powerful is that it is in the process of the whole block, It’s also non-blocking when you read or write data, so some of you might be a little confused here.
Let’s also take the example of thread B going to miss File C’s house for dinner. (All I wanted to do was go to dinner. What were you thinking?)
What about multiplexing IO and signal-driven IO?
Thread B gets notified and goes to miss C’s house, and miss C sees that thread B is coming and starts preparing the food and cooking. Notice that thread B is still waiting for Miss C to prepare the food, and this process is still blocked for thread B.
While asynchronous IO, thread B receives the notification, and then goes to Miss C’s house, enters the file Miss C: Master, the meal is ready, please enjoy.
Eat straight away without waiting. So asynchronous I/O is truly asynchronous, because thread B does not wait at all, but asynchronous I/O requires the support of the operating system kernel.
Write at the end:
See here presumably you have a preliminary understanding of IO model, the subsequent notes on NIO will be released one after another. Finally, if you want to see my notes for the first time, remember to follow me.