【编程进阶知识】IT 技术领域中阻塞、非阻塞、同步、异步概念解析

news/2024/10/19 16:20:54/

摘要: 本文深入探讨了 IT 技术领域中阻塞、非阻塞、同步、异步等关键概念,通过详细的定义、示例、代码片段和流程图加以阐释,并以表格形式进行对比分析。为读者全面理解这些技术概念和应用提供了有价值的参考。

关键词: 阻塞、非阻塞、同步、异步

一、阻塞(Blocking)

  1. 定义
    • 在计算机编程中,阻塞是指一个操作(如函数调用、系统调用等)在完成之前会暂停当前执行的线程或进程,使其进入等待状态,直到该操作完成为止。
  2. 示例
    • 在网络编程中,当使用阻塞式的套接字(Socket)接收数据时,如果没有数据到达,调用接收数据的函数(如recv函数)将会阻塞当前线程,直到有数据可接收或者发生错误。
    • 例如在一个简单的文件读取操作中,如果使用阻塞式的文件读取函数,当文件系统忙于处理其他任务时,读取进程将暂停等待,直到文件读取操作可以继续进行。
  3. Java 代码示例
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class BlockingExample {public static void main(String[] args) {try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {// 这里的 readLine() 方法是阻塞的,会一直等待直到读取到一行数据或文件结束String line = reader.readLine();System.out.println("读取到的数据: " + line);} catch (IOException e) {e.printStackTrace();}}
}
  1. 流程图
graph TD
A[开始] --> B[执行阻塞操作,如文件读取或网络接收]
B --> C[线程进入等待状态,直到操作完成]
C --> D[操作完成,获取结果]
D --> E[继续执行后续代码]
E --> F[结束]

二、非阻塞(Non - blocking)

  1. 定义
    • 非阻塞操作是指操作不会使执行线程或进程进入等待状态。如果操作不能立即完成,它会立即返回一个表示操作未完成的结果(例如错误码或者特殊值),允许程序继续执行其他任务。
  2. 示例
    • 在网络编程中,非阻塞套接字的recv函数调用时,如果没有数据可读,函数不会阻塞,而是立即返回一个特殊值(例如在 Unix 系统中可能返回EWOULDBLOCKEAGAIN),这样程序就可以去执行其他操作,如处理已经接收到的数据或者发送新的数据。
    • 对于非阻塞的文件 I/O 操作,如果文件不能立即被读取,函数会返回一个状态值,程序可以继续处理其他逻辑,之后再轮询查看文件是否可读。
  3. Java 代码示例(使用 Java NIO 的非阻塞示例)
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;public class NonBlockingExample {public static void main(String[] args) throws IOException {// 创建一个非阻塞的 SocketChannelSocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);// 连接到服务器socketChannel.connect(new java.net.InetSocketAddress("localhost", 8080));while (!socketChannel.finishConnect()) {// 可以在这里执行其他任务,因为连接操作是非阻塞的System.out.println("正在连接...");}// 准备发送数据ByteBuffer buffer = ByteBuffer.allocate(1024);buffer.put("Hello, Server!".getBytes());buffer.flip();// 发送数据,这里也是非阻塞的,如果缓冲区已满可能立即返回while (buffer.hasRemaining()) {socketChannel.write(buffer);}// 准备接收数据buffer.clear();// 接收数据,同样是非阻塞的int bytesRead = socketChannel.read(buffer);if (bytesRead > 0) {buffer.flip();byte[] data = new byte[bytesRead];buffer.get(data);System.out.println("接收到的数据: " + new String(data));} else if (bytesRead == -1) {// 连接关闭socketChannel.close();}socketChannel.close();}
}
  1. 流程图
graph TD
A[开始] --> B[执行非阻塞操作]
B --> C[操作立即返回结果或状态,表示是否完成]
C --> D[如果未完成,执行其他任务或轮询检查操作是否完成]
D --> E[当操作完成,获取结果]
E --> F[继续执行后续代码]
F --> G[结束]

三、同步(Synchronous)

  1. 定义
    • 同步操作是指按照顺序依次执行的操作模式。在同步模式下,一个操作必须等待前一个操作完成后才能开始。调用者会在原地等待被调用者的返回结果,在这个过程中调用者不能去做其他事情。
  2. 示例
    • 在单线程的程序中,如果有一系列的数据库操作,如先插入一条记录,然后更新这条记录,在同步模式下,更新操作必须等待插入操作完全成功后才会开始执行。
    • 当使用同步的 HTTP 请求时,发送请求的代码会等待服务器响应返回后才继续执行后续代码,整个流程是顺序执行的。
  3. Java 代码示例(同步 HTTP 请求示例)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;public class SynchronousHttpExample {public static void main(String[] args) {try {// 发送同步 HTTP GET 请求URL url = new URL("https://www.example.com/api/data");HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");int responseCode = connection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String inputLine;StringBuilder response = new StringBuilder();while ((inputLine = in.readLine())!= null) {response.append(inputLine);}in.close();System.out.println("服务器响应: " + response.toString());} else {System.out.println("请求失败,响应代码: " + responseCode);}connection.disconnect();} catch (IOException e) {e.printStackTrace();}}
}
  1. 流程图
graph TD
A[开始] --> B[执行操作 1]
B --> C[等待操作 1 完成]
C --> D[执行操作 2(操作 2 需等待操作 1 完成)]
D --> E[等待操作 2 完成]
E --> F[继续执行后续代码]
F --> G[结束]

四、异步(Asynchronous)

  1. 定义
    • 异步操作是指操作被发起后,调用者不需要等待操作完成就可以继续执行其他操作。当操作完成时,会通过某种方式(如回调函数、事件通知等)通知调用者操作的结果。
  2. 示例
    • 在 JavaScript 中,使用setTimeout函数是异步操作的一个例子。当调用setTimeout时,它会安排一个定时器,然后程序可以继续执行其他代码,当定时器到期时,指定的回调函数会被执行。
    • 在异步的网络请求中,发送请求后,程序可以继续处理其他事务,当服务器响应到达时,通过预先注册的回调函数来处理响应结果。
  3. Java 代码示例(使用 CompletableFuture 实现异步操作)
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class AsynchronousExample {public static void main(String[] args) throws ExecutionException, InterruptedException {// 异步执行一个任务CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000); // 模拟耗时操作return "异步任务完成";} catch (InterruptedException e) {throw new RuntimeException(e);}});// 可以在这里继续执行其他代码,而无需等待异步任务完成System.out.println("主线程继续执行其他任务...");// 获取异步任务的结果(这里会阻塞直到结果可用,但不影响之前代码的异步执行)String result = future.get();System.out.println(result);}
}
  1. 流程图
graph TD
A[开始] --> B[发起异步操作]
B --> C[继续执行其他任务,无需等待异步操作完成]
C --> D[异步操作完成,触发通知(如回调函数执行)]
D --> E[处理异步操作结果]
E --> F[结束]

五、对比表格

概念特点示例场景代码示例特点(简单概括)流程图特点(简单概括)
阻塞操作会暂停线程等待完成网络数据接收、文件读取线程会等待操作完成,如文件读取时直到读取到数据或结束线程在操作未完成时处于等待状态,完成后继续执行
非阻塞操作立即返回状态,不等待完成非阻塞网络编程、文件 I/O操作返回状态值,可继续执行其他任务,如非阻塞 Socket 连接和读写操作返回后可执行其他任务,轮询或等待完成后处理结果
同步按顺序依次执行,等待前一个操作完成数据库系列操作、同步 HTTP 请求按顺序执行,等待操作完成后进行下一步,如同步 HTTP 请求等待响应依次执行操作,每个操作完成后才进行下一个
异步发起后无需等待完成,通过通知获取结果JavaScript 的 setTimeout、异步网络请求发起后可继续执行其他任务,通过回调或 Future 获取结果,如使用 CompletableFuture发起后继续执行,完成后通过通知处理结果

http://www.ppmy.cn/news/1538740.html

相关文章

【编程进阶知识】《探秘防抖机制:让 Web 系统更稳定的魔法》

标题&#xff1a;《探秘防抖机制&#xff1a;让 Web 系统更稳定的魔法》 摘要&#xff1a;本文将深入探讨防抖的概念及在 Web 系统中的重要性。读者将了解到防抖的作用、前端与后端分别如何实现防抖&#xff0c;以及通过 Java 代码片段和流程图更直观地理解防抖机制。同时&…

【java面经thinking】一

目录 类加载过程 加载&#xff1a; 连接 初始化 GC回收机制&#xff08;垃圾回收&#xff09; 区域 判断对象是否存活 回收机制 HashMap 类加载器 加载标识 加载机制 缓存 自定义加载器&#xff1a; JVM内存结构 常量池 string设置成final 按下网址发生 类加…

七、结构型(桥接模式)

桥接模式 概念 桥接模式是一种结构型设计模式&#xff0c;旨在将抽象部分与其实现部分分离&#xff0c;使它们可以独立变化。它通过使用组合关系而非继承来实现接口和实现的解耦&#xff0c;从而提高系统的灵活性和可扩展性。 应用场景 多个维度的变化&#xff1a;当一个系统…

Linux下CMake入门

CMake的基础知识 什么是 CMake CMake 是一个跨平台的构建工具&#xff0c;主要用于管理构建过程。CMake 不直接构建项目&#xff0c;而是生成特定平台上的构建系统&#xff08;如 Unix 下的 Makefile&#xff0c;Windows 下的 Visual Studio 工程&#xff09;&#xff0c;然后…

FireFox简单设置设置

文章目录 一 设置不显示标签页1原来的样子2新的样子3操作方法 二 设置竖直标签页栏1 效果图2 设置方法 三 设置firefox不提醒更新 一 设置不显示标签页 1原来的样子 2新的样子 3操作方法 地址栏输入 about:config搜索icon,双击选项列表中browserchrome.site icons的值&#…

百度搜索引擎(SEO)优化师的未来将何去何从?

百度搜索引擎&#xff08;SEO&#xff09;优化师的未来将何去何从&#xff1f; 作为一名SEO专家&#xff08;林汉文&#xff09;&#xff0c;在过去的三年里&#xff0c;我深感自己与快速变化的百度SEO圈子逐渐脱节。然而&#xff0c;在最近重拾旧业&#xff0c;重新审视SEO特…

postman变量,断言,参数化

环境变量 1.创建环境变量 正式环境是错误的&#xff0c;方便验证环境变化 2.在请求中添加变量 3.运行前选择环境变量 全局变量 能够在任何接口访问的变量 console中打印日志 console.log(responseBody);//将数据解析为json格式 var data JSON.parse(responseBody); conso…

软件供应链十年:探索开源的增长、风险和未来

回顾软件供应链状况报告的 10 年既是一个里程碑&#xff0c;也是一次行动号召。在过去十年中&#xff0c;开源消费改变了软件开发的世界。我们看到了前所未有的创新&#xff0c;但也出现了新的挑战&#xff0c;特别是在管理软件供应链的安全性和完整性方面。 在 Sonatype&…