一、blocking/non-blocking | sync/async
1.blocking/non-blocking: 描述的是方法會不會阻塞線程的執行,使線程進入blocking狀態
2.sync/async:描述的是數據讀寫方式
- sync:用戶線程參與數據讀寫
- 由內核線程發起讀寫,用戶只需要關注I/O完成後的回調,不需要參與具體的I/O過程
二、AIO(Asynchronous Input and Output)
- NIO2.0提出了新異步通道概念,並提供了異步文件通道和異步套接字實現的通道(JDK7)
- 異步套接字通道真正的實現了真正的異步非阻塞I/O
三、三種IO工作原理
四、AIO模型
五、BIO、NIO、AIO
I/O | 數據傳輸 | 時間 | 實現方式 | 使用場景 | 應用 |
---|---|---|---|---|---|
BIO | Stream | JDK1 | Socket | 連接數目比較小且固定的架構 | 一般很少使用 |
NIO | ByteBuffer | JDK4 | Channel Selector | 連接數目多且連接比較短(輕操作)的架構 | 網絡框架netty |
AIO | ByteBuffer | JDK7 | Channel | 連接數目多且連接比較長(重操作)的架構 | Ngix,MySQL新版本 |
六、AIO實現
//TestServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class TestServer {
private AsynchronousServerSocketChannel channel = null;
public TestServer(int port) {
try {
channel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(port));
} catch (IOException e) {
e.printStackTrace();
}
channel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel socket, Void attachment) {
channel.accept(attachment, this);
ByteBuffer byteBuffer = ByteBuffer.allocate(64);
socket.read(byteBuffer);
byteBuffer.flip();
System.out.println(new String(byteBuffer.array()));
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("建立通信失敗");
}
});
}
public static void main(String[] args) {
new TestServer(9000);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//TestClient.java
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
public class TestClient {
public static void main(String[] args) throws Exception {
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
channel.connect(new InetSocketAddress("127.0.0.1", 9000));
ByteBuffer buffer = ByteBuffer.allocate(64);
buffer.put("hello".getBytes());
buffer.flip();
channel.write(buffer);
}
}