1、等待数据准备: 数据从网络接口读取并放入内核缓冲区。
2、拷贝数据: 数据从内核缓冲区复制到应用程序的用户空间。
一次 IO 操作
操作流程分为两步:等待数据准备、拷贝数据
,若等待数据准备过程是阻塞的,则我们称为阻塞操作;若不必等待数据准备完成,而是返回是否就绪标志,则称为非阻塞。IO
操作,阻塞等待 IO
操作完成,则操作是同步的;若用户发起 IO
操作,不必等待操作完成,等待内核完成 IO
操作后通知用户线程,则为异步,如常见的 aio_read 函数
。IO
操作我们一般使用下面三种方式:import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class SynchronousIO {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
优点:编程简单,方便理解
缺点:阻塞读取,效率低下,与 IO 无关的操作也需要等待 IO 完成
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AsynchronousMultiThreadIO {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
});
executor.shutdown();
}
}
优点:多线程处理,提高系统响应速度;充分利用 CPU 资源、避免阻塞其它业务
缺点:上下文切换成本较高,编程复杂度较高,需要管理大量线程
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
public class AsynchronousCallbackIO {
public static void main(String[] args) {
CompletableFuture.runAsync(() -> {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}).thenRun(() -> System.out.println("File reading completed."));
}
}
import reactor.core.publisher.Mono;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ReactiveIO {
public static void main(String[] args) {
Path path = Paths.get("example.txt");
Mono.fromCallable(() -> Files.readString(path))
.subscribe(content -> System.out.println(content),
error -> error.printStackTrace(),
() -> System.out.println("File reading completed."));
}
}
优点:
1、相比多线程 IO,响应式编程的资源开销更低,能够更好地利用系统资源
2、响应式编程模型适合处理高并发、高吞吐量的应用,便于扩展和维护
缺点:
1、学习曲线陡峭:响应式编程需要理解异步编程和回调机制,对于初学者来说可能比较困难
2、调试复杂:由于异步操作的非顺序执行,调试和错误处理变得更加复杂
Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes.
协程是一种计算机程序组件,它通过允许多个入口点在特定位置暂停和恢复执行,将非抢占式多任务的子程序进行了一般化。协程非常适合实现更熟悉的程序组件,如协作任务、异常、事件循环、迭代器、无限列表和管道。
协程(Goroutines)是一种轻量级的并发编程模型,由编程语言或运行时环境管理,用于执行并发任务。与传统的操作系统线程相比,协程更轻量级,切换开销更小,因此在高并发场景中非常高效。协程在许多现代编程语言中都有实现,包括 Go、Python、JavaScript(在某种程度上通过异步函数和生成器)等。
go
示例代码package main
import (
"fmt"
"sync"
"time"
)
// 定义一个 WaitGroup 以等待所有协程完成
var wg sync.WaitGroup
// 定义两个 channel 用于协程间的通信
var ch1 = make(chan int)
var ch2 = make(chan int)
func worker1() {
defer wg.Done() // 在函数结束时减少 WaitGroup 计数
for i := 0; i < 5; i++ {
fmt.Println("Worker 1: Sending", i)
ch1 <- i // 将数据发送到 ch1
time.Sleep(500 * time.Millisecond)
}
close(ch1) // 关闭 channel,通知 worker2 没有更多数据
}
func worker2() {
defer wg.Done() // 在函数结束时减少 WaitGroup 计数
for {
val, ok := <-ch1 // 从 ch1 接收数据
if !ok {
break // 如果 ch1 已关闭,退出循环
}
fmt.Println("Worker 2: Received", val)
fmt.Println("Worker 2: Sending", val*val)
ch2 <- val * val // 将数据发送到 ch2
time.Sleep(500 * time.Millisecond)
}
close(ch2) // 关闭 channel,通知 main 没有更多数据
}
func main() {
// 启动 worker1 和 worker2 协程
wg.Add(2)
go worker1()
go worker2()
// 在主协程中从 ch2 接收数据
go func() {
for val := range ch2 {
fmt.Println("Main: Received", val)
}
}()
wg.Wait() // 等待所有 worker 协程完成
}
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。
🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。
💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。
🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。
📖 保持关注我的博客,让我们共同追求技术卓越。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。