本文讨论近期发布的Java 21。其中新增了一个主要特性,虚拟线程(virtual thread),近期话题不断,我们都知道Golang的协程提供了很好的并发功能。那么就来探讨一下Java 21和 Go 语言中相应的功能。
Golang的协程和Java 21的虚拟线程都是用于构建轻量执行线程的并发技术。它们具有一些相似的特性,但也有着非常大的区别。下面就来比较Golang的协程和Java 21的虚拟线程:
- 并发模型
虚拟线程是Java 21中新推出的并发技术。称为虚拟线程的用户态线程由Java虚拟机线程调度器管理和调度。
而另一边Go语言的并发范式的主要构成部分就是协程。它是由Go运行时管理、Go调度器调度的用户态线程。 - 并行原语
Java为异步编程提供了CompletableFuture类,为传统线程提供了Thread类。Thread API用于管理虚拟线程。
Golang提供了关键字go来启动goroutine,并且内置了channel来支持协程间的同步和数据传输。 - 轻量
Java 21中的虚拟线程可创建大量的虚拟线程,而不占用大量的系统资源,因为它相对轻量。
而在Golang中,可以构造数万甚至数百万的goroutine,因其非常轻量并且有最小化的内存占用。 - 调度
JVM线程调度器,底层会使用多个原生线程来调度虚拟线程。
但Go运行时调度器有效地通过多路复用将协程放到更少和线程上,通常和CPU的内核数相同。 - 错误处理
Java 21添加了一些特性,比如结构化并发结构体,来处理虚拟线程中的错误和异常。
而Golang鼓励返回管理错误的值和通道,来协调跨协程通讯。 - 开发方法
Java具备更全面的类型系统,更倾向于面向对象编程。
Go语言极其注重简洁性,提供了更克制但有用的能力集。 - 原生库和生态
Java可用各种应用,因其具有强大的生态系统和全面的库。
Go语言的生态在不断扩充,在web编程和系统计算领域尤为突出。
使用了goroutine的应用
Golang以其协程和轻量并发范式而闻名。Go-routine用在多种应用中,来一次性有效管理多个进程。以下是一些goroutine的典型场景和应用:
- Web服务端
Go常用创建web服务端,比如著名的‘net/http’ HTTP服务端包。服务端可同时处理多个请求,而又不必为每个连接启动新的操作系统线程,因为每个HTTP请求连接可由一个独立的线程处理。 - 并发模式
goroutine用于实现多种并发模式,如worker池、fan-out/fan-in和并行处理。这些设计模式常用于要求并行和响应的数据处理管道等应用中。 - 微服务
goroutine在微服务设计中用于处理服务之间的通讯并协调并行处理操作。来自其它服务的请求、计算和并发通讯可使用goroutine交给各个微服务处理。 - 并行编程
goroutine可用于需要并行编程的运行,来高效地将任务分发给可并发运行的工作单元。
使用了Go语言和goroutine的大型项目
Go语言及其协程对整个技术界都产生了是影响,并且广泛用于很知名公司的大型产品中:
Kubernetes,知名的窗口编排技术,主要由Go开发,这是Google正在使用的Go项目之一。Go语言还用于Google很多的基础设施即服务(IaaS)和平台即服务(PaaS)的产品中。
Uber
Go用于开发Uber技术栈中的大量组件。创建了大量的Go库和工具,比如Uber Go框架Tchannel,用于创建可扩展的高效微服务。
Docker
容器化平台Docker主要由Go进行开发。Docker使用goroutine和channel来高效管理容器。
Twitch
直播流平台Twitch使用Go来满足其可扩展和低时延性能的要求。它们也开源了几个Go语言项目。
Cloudflare
Cloudflare一家全球内容分发网络(CDN)提供商,使用Go开发serverless服务及其它分发网络对性能要求很高的部分。
DigitalOcean
云基础设施DigitalOcean使用Go来开发网络服务和API,以及其它一些云平台的功能。
Dropbox
Dropbox使用Go提升后端服务的速度和效率,尤其是那些处理文件同步和数据存储的部分。
Stripe
在线支付处理平台Stripe使用Go来创建一些关注时延和并发的后端服务。
参考链接:https://medium.com/@yashgaherwar2002/golang-goroutines-v-s-java-21-virtual-threads-b0bd3e86caa1