java线程和go协程

一、线程的实现

线程的实现方式主要有三种:内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对java的线程比较熟悉一点,所以主要针对java线程和go的协程之间进行一个对比。
线程模型主要有三种:1、内核级别线程;2、用户级别线程;3、混合线程
1、内核级别线程
内核级别线程就是直接由操作系统的内核(kernel)支持的线程,这种方式实现的线程主要通过内核的调度器来进行调度,由内核完成线程切换。一般来讲程序不会直接调用系统内核线程,而是利用内核线程的一种高级接口-轻量级进程(Light Weight Process,即LWP,它也可以视为用户线程),也就是我们平时所说的线程,每一个LWP都是由一个内核线程支持,也就是先有内核线程,再有LWP。这种LWP与内核线程之间1:1的关系称为一对一线程模型,这是一种最简单的线程实现方式。见下图:

2018-11-16 22-40-01 的屏幕截图.png

这种方式创建的每一个线程都需要由一个内核线程支持,需要消耗一定的内核资源,因此一个系统支持的线程数量是有限的。另外由于基于内核线程实现,这种方式创建的线程操作需要进行系统调用,而系统调用代价较高,需要在用户态和内核态进行切换(这个我也不懂)。
2、用户级别线程
这里所指的用户级线程主要是创建在用户空间的线程库上,系统内核感受不到线程的实现方式。用户线程的建立、同步、销毁等在用户态中完成,不需要内核的介入。这种进程和用户线程(UT)之间1:N的关系称为一对多线程模型。

1321313.jpg


这种方式的优势就是上下文切换比较快,缺点是无法从多线程处理器或多处理器计算机上的硬件加速中受益,同时调度的线程永远不会超过一个。
3、混合线程
这种方式相当于是第一种方式和第二种方式的混合,即有LWT,也有用户线程,这种方式中用户线程(UT)和LWT的数量比是不定的,即所谓的N:M关系,也就是所谓的多对多模型。这种实现线程的方式相比前两种也更为复杂,这种方式中由线程库负责在可用的可调度实体上调度用户线程,这使得线程的上下文切换非常快,因为它避免了系统调用。但是增加了复杂性和优先级倒置的可能性,以及在用户态调度程序和内核调度程序之间没有广泛(且高昂)协调的次优调度。

3213213123.jpg

java线程实现

主要说下常用的hotspot的JVM,采用的是第一种1:1的线程模型,即:map a java thread to a native thread,也就是说java线程会和native线程有个一一映射的关系,如果看下java的Thread类就可以发现有很多的native方法,这就涉及到操作系统的线程了。

二、go语言并发模式

go语言支持两种并发模式,一种是Communicating Sequential Processes(CSP)模式,这种模式中值是在相互独立的协程(goroutine)中传递的,协程和协程之间使用到就是上次说到的channel。另外一种就是我们比较传统的模式,也是我们相对熟悉的模式Share Memory Multithreading。但是go语言推荐的还是第一种模式,go官网文档是说:Do not communicate by sharing memory; instead, share memory by communicating.也就是说不建议线程或协程之间通过共享内存通讯,而是通过通讯共享内存。比方说比较熟悉的java其实就是共享内存模式的并发模式,在涉及到多线程的问题时,必须考虑共享数据的安全性。

三、线程和协程之间的区别

这里说的协程指的只是go语言的goroutine。线程和协程的区别主要是数量上的,而不是性质上,所以说协程从逻辑上来说也是线程。

栈的大小:

1、线程栈
操作系统的线程一般都分配有一块固定大小的内存块(一般来说大小是2M,这个需要查证),我查找资料显示的64位Linux上,hotspot虚拟机的栈的大小默认为1M,地址:https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html。。栈存储的是方法的局部变量或者一些基本数据类型(java中)。因为栈的大小是固定的,在执行某些方法的时候可能就不太够用,比如一些比较复杂或则一些深的递归操作,比如熟悉的java有时候会有栈溢出异常;当然某些时候2M可能显得有点大,这样从一定程度上来说又造成了浪费。
2、协程
协程开始的时候也会分配一定大小的内存区域,一般只有2K,和线程的栈一样,协程的栈存储的也是局部变量,但是不同的是协程的栈的大小是不固定的,是可以根据需要自动调整大小的,最大甚至可以达到1G,所以灵活性非常好。

调度方式

1、系统级别的线程是由操作系统的内核(kernel)调度的,每过几毫秒,硬件的计时器就会中断处理器,从而引起被成为调度器的内核函数执行。调度器会暂停当前正在执行的线程,并把它的寄存器存到内存中,并查看线程列表决定接下来执行哪一个线程,然后从内存中恢复改线程的寄存器,最后恢复该线程的执行。因为线程是通过内核调度的,从一个线程切换到另一个线程就涉及到上下文转换,建议看下维基百科:https://en.wikipedia.org/wiki/Context_switch。简单说就是将一个用户线程的状态保存到内存,恢复另一个用户线程的状态,并且更新调度程序的数据结构,导致上下文切换比较慢。
2、go语言使用了所谓的N:M调度的技术实现了自己的调度器,它在N个系统线程上多路复用(或调度)M个协程,也就是说由n个系统线程,生成了m个go的协程(可以这么理解吧?)。go语言的调度工作类似于系统内核的调度,但是它只关注单个go程序的协程。
另外一点就是go的协程是没有标识的,在java中当前执行的线程都会有一个唯一的标识,它的好处就是可以很容易的就构建出一个抽像的"thread-local storage",即java中的ThreadLocal,每个线程都可以创建出这样一个数据结构存储只属于当前线程的一些变量。但是goroutine并不支持,因为ThreadLocal可能会被滥用。go语言提倡的是一种更简单的编程方式,即参数影响函数的行为应该是显性的。

go因为在创建协程的数量上一般没有特别的限制,所以可以很轻松的创建出很多个协程出来,而java因为采用的是1:1的线程模型,线程数量特别是并发线程数会受到CPU和操作系统的限制(我记得java线程池会获取当前可使用的CPU核数,可能有误),所以并发性能上应该不如go语言,有人也说go语言天生就带有高并发光环加持。这里无意区分java和go孰优孰劣,只是想从线程和协程的实现上来简单的了解下二者的差别。



作者:非典型_程序员
链接:https://www.jianshu.com/p/6168b10dee34
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

java线程和go协程 - 简书

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

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

相关文章

Unittest自动化测试框架vs Pytest自动化测试框架

引言   前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架,大家平时经常使用的是unittest,因为它比较基础,并且可以进行二次开发,如果你的开发水平很高,集成开发自动化测试平台也是可以的。而这篇文章…

如何培养潜在客户?看完这篇你就懂了

图片来源于:SaleSmartly官网 有效的潜在客户培育策略将帮助您将更多潜在客户转化为付费客户。 但是,这并不总是那么容易——您必须与其他公司争夺受众的注意力,并向您的领导证明为什么值得投资您的产品或服务。在本文中,我将向您展…

STM32 RTC实验

RTC时钟简介 STM32F103的实时时钟(RTC)是一个独立的定时器。 STM32的RTC模块拥有一组连续计数的计数器,在相对应的软件配置下,可提供时钟日历的功能。 修改计数器的值可以重新设置系统的当前时间和日期。 RTC模块和时钟配置系统…

iKeyPrime完美解4G信号,可以登录iCloud,有消息通知,支持最新iOS16.6。

iKeyPrime是一款绕过激活锁界面的解锁工具,可以激活所有iPhone苹果手机,二网/三网恢复信号,并且支持插卡接打电话、收发短信、4G流量上网,支持iCloud登录,有消息通知,支持iPhone5S~X的所有型号,…

精益制造、质量管控,盛虹百世慧共同启动MOM(制造运营管理)

百世慧科技依托在电池智能制造行业中的丰富经验,与盛虹动能达成合作,为其提供MOM制造运营管理平台,并以此为起点,全面提升盛虹动能的制造管理水平与运营体系。 行业困境 中国动力电池已然发展为全球最大的电池产业,但…

[ROS]yolov7部署ROS

Yolov7是一种基于PyTorch深度学习框架的目标检测算法,具有高精度和快速的特点,被广泛应用于机器人领域。将Yolov7部署到ROS中可以方便地实现机器人对环境的感知和理解。 在部署Yolov7到ROS之前,需要准备以下环境和工具: Ubuntu …

Netty—FuturePromise

Netty—Future&Promise 一、JDK原生 Future二、Netty包下的 Future三、Promise1、使用Promise同步获取结果2、使用Promise异步获取结果.3、使用Promise同步获取异常 - sync & get4、使用Promise同步获取异常 - await5、使用Promise异步获取异常 在异步处理时&#xff0…

Img标签的src地址自动拼接本地域名(localhost:8080)导致图片不显示问题

摘要:做Vueelement ui项目的时候,发现使用element ui的upload上传图片时,不显示的问题。我项目的图片是上传到七牛云,长传成功后返回存储在七牛云中的地址。后面发现是因为返回的地址是外部地址,需要完整的URL&#xf…

Android大厂需要刷的(999道)面试题

想必大家都在为今年的金九银十做准备,今年也是最为艰难的一年。作为程序员从未感觉到如此艰难,身边不是被辞退就是找不到工作。先不说2023年应届生毕业即失业,作为开发15年的老Android程序员,现在也在和300个人挣一个岗位。 肉少…

使用Dbeaver连接GaussDB

1.下载DBeaver,官网地址 2.安装软件,打开软件,点击数据库->驱动管理器,具体操作如下图: 3、选择新建后进行参数设置,如下图: 具体参数如下图 驱动名称: GS #随便定义 驱动类型&#…

Docker-安装(Linux,Windows)

目录 前言安装版本Docker版本说明前提条件Linux安装使用YUM源部署获取阿里云开源镜像站YUM源文件安装Docker-ce配置Docker Daemon启动文件启动Docker服务并查看已安装版本 使用二进制文件部署 Windows安装实现原理安装步骤基本使用 参考说明 前言 本文主要说明Docker及其相关组…

如何使用代理配置快速定位接口测试脚本问题?

在调试接口用例过程中,如果响应结果和预期结果不一致,则需要检查请求信息。通过代理获取自动化测试中的请求响应信息,对比与正常请求响应的区别,就能够更直观的排查请求错误,相当于编写代码时的 debug 功能。 实战练习…

软件上线测评报告怎么做?

软件上线测试 软件上线前必须经过一个整体的测评,从而帮助企业了解软件的运行情况。软件上线测评检测报告(软件产品测试报告)也通常被称为:科技项目验收测试报告、(软件类)科技成果鉴定测试、软件检测报告…

cron介绍

cron表达式在线生成 在使用定时调度任务的时候,我们最常用的,就是cron表达式了。通过cron表达式来指定任务在某个时间点或者周期性的执行。 cron表达式的组成 cron表达式是一个字符串,由6到7个字段组成,用空格分隔。其中前6个字…

解决uniapp下拉框 内容被覆盖的问题

1. 下拉框 内容被覆盖的问题 场景: 现在是下拉框被表格覆盖了 解决办法: 在表格上添加css 样式来解决这个问题 .add-table{display: static;overflow: visible; } display: static: 将元素会按照默认的布局方式进行显示,不会分为块状或行内元素。 overflow: vi…

NAT地址转换,路由器作为出口设备,实现负载分担

路漫漫其修远兮,吾将上下而求索 一个善于创造的人,一定是一个善于分享的人。 今天整理了一个实验,具备NAT地址转换,路由器作为出口设备,实现负载分担,实现路由策略 目录 实验图 实验要求 实验配置 基…

Linux--I/O复用之select

目录 一:概念 二:使用 三:参数介绍: 1.ndfs: 2.fd_set类型: 3.readfds: 4.writefds: 5.exceptfds: 6.timeout: 7.返回值: 四&#xff1…

2023年7月京东投影仪行业品牌销售排行榜(京东大数据)

鲸参谋监测的京东平台7月份投影仪行业销售数据已出炉! 7月份,投影仪市场呈现增长趋势。根据鲸参谋平台的数据可知,7月京东平台投影仪的销量将近20万,同比增长约16%;销售额将近3.8亿,同比增长约4%。 ​*数据…

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决:在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…

Tequila Works x Incredibuild

关于 Tequila Works Tequila Works 是一家位于西班牙马德里的电子游戏开发商,由劳尔鲁比奥 (Raul Rubio) 和卢兹桑乔 (Luz Sancho) 于2009年创立。该公司著名的游戏产品包括《死亡曙光》(Deadlight)、《霜华》(Rime)、《联盟外传:努努之歌》(Song of Nu…