系统线程和goroutine的区别

从栈空间上,goroutine的栈空间更加动态灵活。

每个OS的线程都有一个固定大小的栈内存,通常是2MB,栈内存用于保存线程执行期间的局部变量,且大小是固定不变的,在多变的场景下,这样固定大小的栈,既太大,又太小,往往不能满足多变的场景。
2MB固定大小的栈,对于执行简单操作的goroutine来说,是一种巨大的浪费;但对于执行高度复杂的goroutine来说,又太过于小了。为了适应不同场景,goroutine在生命周期开始时只有一个很小的栈,典型情况是2KB, 在go程序中,一次创建十万左右的goroutine也不罕见(2KB*100,000=200MB)。而且goroutine的栈不是固定大小,它可以按需增大和缩小,最大限制可以到1GB。

从调度上看,goroutine的调度开销远远小于线程调度开销。

OS的线程由OS内核调度,每隔几毫秒,硬件就发送中断到CPU,CPU调用调度器内核函数,进而引发当前线程的暂停和下个线程的运行,而线程与线程之间的切换,需要一个完整的上下文切换。由于引发内存访问数量的增加和CPU等待周期的增加,这一操作是非常耗时的。
但是Go运行的时候包含一个自己的调度器,这个调度器使用一个称为一个M:N调度技术,把m个goroutine调度到n个os线程上运行,我们可以用GOMAXPROCS来控制n的数量,Go的调度器不是由硬件时钟来定期触发的,而是由特定的go语言结构来触发的,全部在用户态实现,不需要切换到内核语境,因此调度一个goroutine比调度一个线程

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go 语言的协程(Goroutine)和 Java 的线程(Thread)在很多方面有所不同。 首先,Goroutine调度和执行上更加高效。Go 语言的调度器可以在多个线程上运行数千个协程,并且自动处理调度和资源管理。与之相比,Java 线程调度由 JVM 进行管理,创建和销毁线程的成本相对较高。 其次,Goroutine 的内存消耗较小。Goroutine 的栈大小通常只有几 KB,而 Java 线程默认的栈大小为几百 KB。这使得 Goroutine 创建和销毁的成本更低,可以更好地支持大规模并发。 此外,Goroutine 的通信机制更加简单和高效。Go 语言提供了轻量级的通道(Channel)用于协程之间的通信和同步。而在 Java 中,线程之间的通信需要使用底层的锁、条件变量等机制,编写复杂且容易出错。 然而,Java 的线程也有它的优势。Java 线程可以使用更多的底层系统资源,例如底层操作系统线程和多核 CPU 的并行计算。这使得 Java 线程适用于更加复杂和底层的系统级开发。而 Goroutine 主要用于高性能、高并发的轻量级并发编程。 最后,Goroutine 对于错误处理和防止资源泄漏有更好的支持。Go 语言的错误处理机制更加简洁和明确,并且协程的生命周期通常与错误处理机制紧密结合。在 Java 中,需要显式地进行异常处理,否则可能会导致资源无法释放或程序崩溃。 总之,Go 语言的协程和 Java 的线程调度、执行效率、资源消耗、通信机制等方面存在差异。选择使用哪种并发机制取决于具体的应用场景和需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值