BIO-阻塞IO的含义
阻塞(blocking)IO :资源不可用时,IO请求一直阻塞,直到反馈结果(有数据或者超时)。
非阻塞(non-blocking)IO :资源不可用时,IO请求离开返回,返回数据标识资源不可用。
同步(synchronous)IO : 应用阻塞在发送或接收数据的状态,直到数据成功传输或返回失败。
异步(asynchronous)IO :应用发送或接收数据后立刻返回,实际处理时异步执行的。
阻塞和非阻塞是获取资源的方式,同步、异步是程序如何处理资源的逻辑设计。
代码中使用的API:
ServerSocket #accept
InputStream#read
都是阻塞的API,操作系统底层API中,默认Socket操作都是Blocking型。
阻塞带来的问题:阻塞导致在处理网络I/O时,一个线程只能处理一个网络连接,浪费资源。
下面时一个简单的代码示例:
服务器端代码:
package com.nipx.demo.aio;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BIO_server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("容器启动");
while (!serverSocket.isClosed()) {
//阻塞,线程到达此处之后,如果没有连接,则一直等待连接
Socket accept = serverSocket.accept();
System.out.println("收到新连接:" + accept.toString());
//io + net
InputStream inputStream = accept.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String msg;
while ((msg = reader.readLine()) != null) { //没有数据,阻塞
if (msg.length() == 0) {
break;
}
System.out.println(msg);
}
System.out.println("接收到数据:" + accept.toString());
accept.close();
serverSocket.close();
}
}
}
客户端代码:
package com.nipx.demo.aio;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.Scanner;
public class BIO_client {
private static Charset charset = Charset.forName("UTF-8");
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
String msg = scanner.nextLine();
outputStream.write(msg.getBytes(charset));
scanner.close();
socket.close();
}
}
首先运行服务器端:运行结果如
然后运行客户端:运行结果如:输入123,回车。
服务器接收到的数据,如下结果:
一个简单的示例,帮助大家理解BIO的一个应用。