什么是阻塞IO?

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
简介: **阻塞IO是一种IO操作模式,使得调用线程在IO未完成时会暂停,等待操作完成。简单但可能导致线程阻塞,适用于低并发、长处理场景。Java示例中,`ServerSocket`和`Socket`展示了这种模式。服务端接收到客户端连接后读取数据,回应"Echo",每个连接需单独线程处理。高并发时可考虑非阻塞IO(NIO)或异步IO来优化。**

阻塞IO的概念

阻塞IO(Blocking IO)是一种IO操作模式。在这种模式下,当一个IO操作(如读、写)执行时,如果不能立即完成操作,程序会暂停执行,直到操作完成。简单来说,阻塞IO会使调用线程等待IO操作的完成,无法继续处理其他任务。

特点

  • 简单性:编程模型简单,易于理解和实现。
  • 线程阻塞:IO操作会导致线程阻塞,等待IO操作完成。
  • 适用场景:适用于连接数较少且每个连接需要较长时间处理的场景,以字节为传输单位。

阻塞IO的Java示例

下面是一个使用Java进行阻塞IO操作的简单示例。这段代码展示了如何使用ServerSocketSocket进行阻塞IO操作。

代码示例

服务端代码

java

代码解读

复制代码

public class TCPServer {  
  
    public static void main(String[] args) throws IOException {  
        System.out.println("服务的启动...");  
        System.out.println("开始监听9999端口");  
        ServerSocket ss = new ServerSocket(9999);  
        while (true){  
            // 等待客户端连接  
            Socket accept = ss.accept();  
            // 处理客户端请求  
            InputStream is = accept.getInputStream();  
            byte[] b = new byte[10];  
            is.read(b);  
            String clientIP = accept.getInetAddress().getHostAddress();  
            System.out.println(clientIP + "说:" + new String(b));  
            // 回复客户端消息  
            OutputStream os = accept.getOutputStream();  
            os.write("Echo".getBytes());  
            // 关闭  
            accept.close();  
        }  
    }  
}

客户端代码

java

代码解读

复制代码

public class TCPClient {  
    public static void main(String[] args) throws IOException {  
        while (true){  
            //创建socket对象  
            Socket s = new Socket("127.0.0.1", 9999);  
            OutputStream os = s.getOutputStream();  
            System.out.println("请输入:");  
            Scanner sc = new Scanner(System.in);  
            String input = sc.nextLine();  
            os.write(input.getBytes());  
            //获得服务端的响应  
            byte[] b = new byte[1024];  
            int len = s.getInputStream().read(b);  
            System.out.println("服务端回复:" + new String(b, 0, len));  
            //关闭连接  
            s.close();  
        }  
    }  
}

运行说明

  1. 启动服务端:首先编译并运行TCPServer。服务端会在9999端口上监听客户端连接。
  2. 启动客户端:然后编译并运行TCPClient。客户端会连接到服务端,并可以输入消息发送到服务端。
  3. 交互:客户端发送的每条消息,服务端会接收并返回一个“Echo”响应。

总结

阻塞IO适用于简单的网络应用,但在高并发场景下效率较低,因为每个连接会占用一个线程,可能导致线程资源耗尽。为了解决高并发问题,可以使用非阻塞IO(如NIO)或异步IO技术。


转载来源:https://juejin.cn/post/7390686791776862235

相关文章
|
6月前
|
Linux C++
|
6月前
|
存储 Java 芯片
BIO 阻塞IO流 数据存储
为了弄清楚 I/O 流 的执行原理,首先需要了解数据在磁盘中的存储方式。目前进行数据存储的磁盘分为两种:机械磁盘、固态硬盘。
|
5月前
|
Java Unix Linux
什么是阻塞IO和非阻塞IO
什么是阻塞IO和非阻塞IO
121 3
|
27天前
|
存储 缓存 算法
如何优化阻塞IO的性能?
【10月更文挑战第6天】如何优化阻塞IO的性能?
31 5
|
3月前
|
存储 Java 数据库连接
BIO阻塞IO流与数据存储大揭秘:性能与资源消耗,一文让你彻底解锁!
【8月更文挑战第25天】本文探讨了Java中BIO阻塞IO流与数据存储的概念及其实现。BIO作为一种传统IO模型,在处理每个客户端请求时需创建新线程并等待响应,这在并发量大时会导致性能下降和高资源消耗。示例代码展示了如何利用`ServerSocket`实现基于BIO的简单服务器。此外,文章还介绍了数据存储的基本方法,例如通过`BufferedWriter`向文件写入数据。两者对比显示,BIO适合连接数稳定的场景,而数据存储则适用于需要持久化保存信息的情况。通过这些分析和实例,希望能帮助读者更好地掌握这两种技术的应用场景及其优缺点。
43 0
|
3月前
|
C# 开发者 设计模式
WPF开发者必读:命令模式应用秘籍,轻松简化UI与业务逻辑交互,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,命令模式是简化UI与业务逻辑交互的关键技术,通过将请求封装为对象,实现UI操作与业务逻辑分离,便于代码维护与扩展。本文介绍命令模式的概念及实现方法,包括使用`ICommand`接口、`RelayCommand`类及自定义命令等方式,并提供示例代码展示如何在项目中应用命令模式。
46 0
|
3月前
|
Ubuntu Linux
内核实验(九):添加IO驱动的阻塞读写功能
本文通过修改内核模块代码,介绍了如何在Linux内核中为IO驱动添加阻塞读写功能,使用等待队列和条件唤醒机制来实现读写操作的阻塞和非阻塞模式,并在Qemu虚拟机上进行了编译、部署和测试。
16 0
|
4月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
185 1
|
12月前
阻塞IO、非阻塞IO和IO复用有啥区别?
阻塞IO、非阻塞IO和IO复用有啥区别?
117 1
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。