什么是协程

9 篇文章 0 订阅
本文探讨了Go语言中的协程如何通过自定义调度机制解决线程阻塞问题,与Java线程池的对比,以及Go协程的实现方式,包括有栈协程(如Go的groutine)和无栈协程(如Rust)。重点在于协程如何通过状态机设计消除阻塞,提高并发性能。
摘要由CSDN通过智能技术生成

概述

随着GO的流行,协程概念讨论越来越多,用一篇文章记录协程

协程

线程

在java中线程是一个重要概念,程序想要高性能高并发就离不开线程

  • 在使用线程中一般会用线程池,即用有限的线程执行大量并发任务,以期达到减少线程数量,线程创建、关闭、切换的开销。
  • 单单线程池还不足以支持高并发,在执行过程中有阻塞就会在一定程度上导致性能下降–>消除阻塞。
    • 阻塞原因:sleep、wait、IO(read、write)
    • 解决办法:io->NIO、sleep->回调(代码会被切分很多段,不符合人体工学难读->vertx)

协程

为了解决阻塞的问题,不让他阻塞,而是通过事件完成进行通知。即让线程切走执行其他任务,在完成任务后进行。执行sleep之前先注册一个事件,1s后唤醒接着上次的代码执行(java搞不了:要记住已经执行到了哪一行+保存上阶段所有变量,但是java中程序员无法控制线程切换)。

  • Go实现了一个调度器,现在调度器注册,调度器会到时候唤醒、同时保存了栈和变量即go自己实现了一个类似线程切换。唤醒后可以获得栈的内容,重新扔到线程池中,恢复内容->继续执行

    • 相当于原来系统中有一个调度器,控制线程切换,但是这是内核的功能程序员没法控制,go完成了把内容保存到自己的栈上,在自己的线程之上又完成了一种调度,消除了阻塞,线程没有阻塞会接着执行别的事情。
    • 自己实现栈切换—>实现二次调度---->消除阻塞
    • 协程的目的就是为了消除阻塞。
  • 协程实现方式:

    • 有栈协程:Go Groutine
    • 无栈协程:Rust
      • 若有一个Task在执行的时候需要进行阻塞,基本思路也是从阻塞的位子切出,完成切回;需要有一个调度器,在Task本身记一个状态,在编译的时候阻塞的位置前后会被切分为两块,同时增加一个状态位,记录当前需要执行的代码块。在阻塞的时候记录位置,切到其他地方,完成之后切回来检查该执行哪块代码块,接着执行。(将任务编译为一个状态机)->切分为多个不阻塞的代码块->在多个代码块之间执行。
      • 跳过阻塞代码块

总结

没有协程的性能不一定比协程低,只是通过回调不好读,不满足人体工学,协程要进行调度,代码实际多了,java技巧好了性能实际可以达到比go强,java代码复杂也可以达到很高并发,Go的高并发可以相当简单达到。

java可以实现但是需要技巧
Go可以实现且门槛低

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值