什么是协程?协程和线程的区别

文章目录

  • 前置知识
    • 应用程序和内核
    • 阻塞和非阻塞
    • 同步和异步
    • 并发和并行
    • IO 发展历史
      • 同步编程
      • 异步多线程/进程
      • 异步消息 + 回调函数(响应式编程)
  • 协程
    • 协程基本概念
    • `go` 示例代码
    • 协程和线程的区别
  • 个人简介

前置知识

  • 在了解协程前,我们先理解一些相关的基本知识。

应用程序和内核

unix.jpg

  • 内核具有最高权限,可以访问受保护的内存空间,可以访问底层的硬件设备。而这些是应用程序所不具备的,但应用程序可以通过调用内核提供的接口来间接访问或操作。
  • 以一次网络 IO 操作为例,请求的数据会先被拷贝到系统内核的缓冲区(内核空间),然后再从内核缓冲区拷贝到应用程序的地址空间(用户空间)。这个过程包括两个阶段:
1、等待数据准备: 数据从网络接口读取并放入内核缓冲区。
2、拷贝数据: 数据从内核缓冲区复制到应用程序的用户空间。

阻塞和非阻塞

  • 从上面我们可以清楚的知道, 一次 IO 操作 操作流程分为两步:等待数据准备、拷贝数据,若等待数据准备过程是阻塞的,则我们称为阻塞操作;若不必等待数据准备完成,而是返回是否就绪标志,则称为非阻塞。

同步和异步

  • 用户线程发起 IO 操作,阻塞等待 IO 操作完成,则操作是同步的;若用户发起 IO 操作,不必等待操作完成,等待内核完成 IO 操作后通知用户线程,则为异步,如常见的 aio_read 函数

并发和并行

  • 并发(concurrency):逻辑上具备同时处理多个任务的能力。
  • 并行(parallesim):物理上在同一时刻执行多个并发任务,依赖多核处理器等物理设备。

IO 发展历史

  • 在没有协程的时代,处理 IO 操作我们一般使用下面三种方式:

同步编程

  • 应用程序阻塞等待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 完成

异步多线程/进程

  • 将IO操作频繁的逻辑、或者单纯的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 资源、避免阻塞其它业务
缺点:上下文切换成本较高,编程复杂度较高,需要管理大量线程

异步消息 + 回调函数(响应式编程)

  • 在响应式编程中,IO 操作是非阻塞的,并且通过回调函数来处理结果。

  • 示例代码(使用 CompletableFuture)

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."));}
}
  • 示例代码(使用 Reactor):
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 示例代码

  • 下面是一个使用 Go 协程协作的示例,这个示例展示了如何使用 sync.WaitGroup 和 channel 来实现协程之间的协作:
package mainimport ("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 // 将数据发送到 ch1time.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 // 将数据发送到 ch2time.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编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

强化学习原理入门-1绪论

1 绪论 1.1 这是一本什么书 强化学习算法&#xff1f; AlphaGo大胜世界围棋冠军李世石和柯洁事件&#xff0c;核心算法就用到了强化学习算法。 1.2 强化学习解决什么问题 案例1 非线性系统二级倒立摆 案例2 AlphaGo与柯洁的第二局棋 案例3 机器人学习站立 ...... 智能…

沙箱在“一机两用”新规下的价值体现

在数字化时代&#xff0c;随着企业信息化建设的深入&#xff0c;数据安全问题愈发凸显其重要性。一机两用新规的出台&#xff0c;旨在通过技术创新和管理手段&#xff0c;实现终端设备的安全可控&#xff0c;确保敏感数据的安全存储与传输。SDC沙箱技术作为一种创新的安全防护手…

springcloud-config服务器,同样的配置在linux环境下不生效

原本在windows下能争取的获取远程配置但是部署到linux上死活都没有内容&#xff0c;然后开始了远程调试&#xff0c;这里顺带讲解下获取配置文件如果使用的是Git源&#xff0c;config service是如何响应接口并返回配置信息的。先说问题&#xff0c;我的服务名原本是abc-abc-abc…

图像基础知识入门【图像概念不同图像格式】

图像基础知识入门【图像概念&不同图像格式】 最近有在处理图像转换&#xff0c;因此稍微补足了一下图像相关知识&#xff0c;特在此记录。下面汇总是我根据自己理解和网上查阅资料而来。如有错误&#xff0c;欢迎大家指正。 1 基础概念 像素/分辨率 像素(Pixel)&#xff…

如何实现电子签名签章功能?

随着技术的发展&#xff0c;传统的纸质合同签署方式逐渐暴露出效率低下、存储不便和安全性不足等问题。为了解决这些问题&#xff0c;电子签署服务为用户提供了一个安全、高效、环保的合同管理解决方案。 电子合同管理与签署平台的核心功能 1、用户管理&#xff1a;平台提供用…

怎么永久禁止win10系统自动更新?一键屏蔽系统自动更新

现在 Windows 10 系统是很多办公用户的主力操作系统&#xff0c;可是 Windows 系统会自动更新&#xff0c;这会严重影响系统稳定性。因为微软虽然以提供更新为服务&#xff0c;但并不是每次更新它都是安全的。 接下来和我一起看看如何使用联想开发的小工具一键屏蔽系统自动更新…

MQTT协议详述

MQTT 概述 消息队列遥测传输&#xff08;英语&#xff1a;Message Queuing Telemetry Transport&#xff0c;缩写&#xff1a;MQTT&#xff09;&#xff0c;是基于发布&#xff08;Publish&#xff09;/订阅&#xff08;Subscribe&#xff09;范式的消息协议&#xff0c;位于…

为什么80%的码农都做不了架构师?

文章目录 一、技术广度和深度的要求1.1 技术广度1.2 技术深度 二、全局视角和系统思维2.1 全局视角2.2 系统思维 三、沟通能力和团队合作3.1 沟通能力3.2 团队合作 四、业务理解和需求分析4.1 业务理解4.2 需求分析 五、持续学习和创新能力5.1 持续学习5.2 创新能力 六、总结 &…

【UML用户指南】-25-对高级行为建模-时间和空间

目录 1、概念 2、时间 3、位置 4、常用建模技术 4.1、对定时约束建模 4.2、对对象的分布建模 分布式系统是这样一个系统&#xff0c;它的构件可以物理地分布在各个结点上。 为了表达对实时系统和分布式系统建模的需要&#xff0c;UML 提供了定时标记、时间表达式、定时约…

抛弃 Neofetch?众多优秀替代方案等你体验!

目录 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验Neofetch 的替代品FastfetchscreenFetchmacchina 抛弃 Neofetch&#xff1f;众多优秀替代方案等你体验 NeoFetch 是用 Bash 3.2 编写的命令行系统信息工具&#xff0c;该项目的主要开发人员已将 GitHub 存储库存档&…

民生银行收大额罚单:信用卡中心一同被罚,管理层如何施救?

民生银行的2024年&#xff0c;再添变故。 近日&#xff0c;国家金融监管总局宁波分局公布了数则行政处罚信息公开表。内容显示&#xff0c;民生银行&#xff08;SH:600016、HK:01988&#xff09;宁波分行、民生银行信用卡中心宁波分中心因多项违法违规事实&#xff0c;共计被处…

JVM原理(八):JVM虚拟机工具之基础故障工具

这里主要介绍监视虚拟机运行状态和进行故障处理的工具 1. jsp:虚拟机进程状况工具 jsp命令格式&#xff1a; jsp [options] [hostid] jps远程查询虚拟机进程状态 2. jstat:虚拟机统计信息监视工具 jstat命令格式&#xff1a; jstat [option vmid [interval [s|ms] [count]…

LP-SCADA系统在智能制造中的作用是什么?

在企业思考如何提升产线自动化时&#xff0c;往往考虑到的都是从硬件设备下手&#xff0c;但其实作为“大脑”存在的软件系统更是必不可少&#xff0c;尤其是当产线中的自动化设备越来越多&#xff0c;产生的数据也越来越多&#xff0c;大量数据需要人工进行整理时&#xff0c;…

论文阅读YOLO-World: Real-Time Open-Vocabulary Object Detection

核心&#xff1a; 开放词汇的实时的yolo检测器。重参数化的视觉语言聚合路径模块Re-parameterizable VisionLanguage Path Aggregation Network (RepVL-PAN)实时核心&#xff1a;轻量化的检测器离线词汇推理过程重参数化 方法 预训练方案&#xff1a;将实例注释重新定义为区域…

【24医学顶刊】GANDALF:主动学习 + 图注意力变换器 + 变分自编码器,改善多标签图像分类

GANDALF&#xff1a;主动学习 图注意力变换器 变分自编码器&#xff0c;改善多标签图像分类 提出背景子解法1&#xff1a;多标签信息样本的选择子解法2&#xff1a;生成信息丰富且非冗余的合成样本 例子&#xff1a;胸部X射线图像分析传统方法的操作和局限GaNDLF方法的优势 工…

超级会员卡积分收银系统小程序源码系统 前后端完整分离 带完整的安装代码包以及搭建教程

系统概述 超级会员卡积分收银系统小程序源码系统是专为各类商业场景设计的综合性平台。它旨在为商家提供一站式的解决方案&#xff0c;涵盖了会员管理、积分体系、收银操作以及数据统计等多个重要方面。 该系统的前后端分离架构确保了系统的灵活性和可扩展性。前端负责用户界…

如何用程序批量下载小红书的图片?

如何使用MediaCrawler快速下载图片 作为一名图像算法工程师&#xff0c;怎么能没有图片资源呢&#xff1f;今天&#xff0c;我要介绍一个能快速下载图片的方法&#xff0c;仅供学习使用&#xff0c;请勿用于其他用途。 下载项目 首先&#xff0c;从GitHub下载项目&#xff1…

强化学习的数学原理:贝尔曼公式

大纲 这一节课程的大纲&#xff1a; 重点 对于这次课&#xff0c;重点是两个东西&#xff1a; Motivating examples(为什么需要贝尔曼公式) 首先要明白&#xff0c;为什么 return 是重要的&#xff1f; 之前其实就说过&#xff0c;return 能够帮助我们评价一个策略是好还是坏…

LVGL实现字库的下载和使用

1 字库 字库的概念&#xff1a;相应文字或字符的合集。 点阵字库&#xff1a;按字库顺序排列的字符/汉字字模的合集。 LVGL中字库使用Unicode编码&#xff0c;Unicode 是全球文字统一编码。它把世界上的各种文字的每一个字符指定唯一编码&#xff0c;实现跨语种、跨平台的应…