Netty基础------ BIO(同步阻塞IO)
目录
1、什么是BIO
- Java BIo就是传统的 java io编程,其相关的类和接口在 java.io
- BlO( blocking I/O):同步阻塞,我们熟知的Socket编程就是BIO,每个请求对应一个线程去处理。一个socket连接一个处理线程(这个线程负责这个Socket连接的一系列数据传输操作)。阻塞的原因在于:操作系统允许的线程数量是有限的,多个socket申请与服务端建立连接时,服务端不能提供相应数量的处理线程,没有分配到处理线程的连接就会阻塞等待或被拒绝。
- BO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序简单易理解。
2、BIO的工作机制
对BO编程流程的梳理:
- 服务器端启动一个 ServerSocket
- 客户端启动 Socket对服务器进行通信,默认情况下服务器端需要对每个客户建立一个线程与之通讯
- 客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝
- 如果有响应,客户端线程会等待请求结束后,在继续执行
针对上面的情况,我们可以使用线程池进行一定的优化。但这种优化仅仅是解决了频繁的创建线程的问题,不过由于是同步,如果读写速度慢,那么每个线程进来是会导致阻塞的,性能的高低完全取决于阻塞的时间。这个对于用户的体验也是相当不好的
如下:
3、代码实操演示
package com.BIO;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author: zps
**/
public class BioServer {
public static void main(String[] args) {
//线程池
ExecutorService executorService = Executors.newCachedThreadPool();
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务器已经启动!");
while (true){
Socket socket = serverSocket.accept();
System.out.println("有一个客户端连接!");
//放入线程池中处理请求
executorService.execute(()->
handler(socket));
}
} catch (Exception e) {
e.printStackTrace();
}
}
//处理请求
private static void handler(Socket socket) {
try {
InputStream in = socket.getInputStream();
byte[] bytes = new byte[1024];
while (true){
System.out.println("读到客户端发过来的消息为:");
int read = in.read(bytes);
if(read != -1){
System.out.println(new String(bytes , 0 , read));
}else {
break;
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.BIO;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
/**
* @author: zps
**/
public class BioClient {
public static void main(String[] args) {
OutputStream os = null;
Socket socket = null;
try {
socket = new Socket("localhost", 8080);
os = socket.getOutputStream();
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String msg = sc.nextLine();
os.write(msg.getBytes());
}
os.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行截图:
4、总结
BIO其实就是一种同步阻塞的IO的操作。
阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候。
- 阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否则一直等待在那里。
- 非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回。
从上面的实例中,客户端的每一个请求,服务端都会启动一个线程进行处理,并且会一直到客户端退出连接为止。但这样明显有一种缺点就是当客户端暂时没有发送的数据时,服务端的线程依旧会等待着,所以就会浪费了线程资源的浪费。那么就有了NIO,NIO与BIO的最大区别就是NIO是非阻塞的。
未完-----