java线程和go协程

news2024/11/24 12:05:49

一、线程的实现

线程的实现方式主要有三种:内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对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.coloradmin.cn/o/970578.html

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

相关文章

微服务主流框架概览

微服务主流框架概览 目录概述需求: 设计思路实现思路分析1.HSF2.Dubbo 3.Spring Cloud5.gRPC Service mesh 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a be…

深入理解作用域、作用域链和闭包

​ 🎬 岸边的风:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想,就是为了理想的生活 ! ​ 目录 📚 前言 📘 1. 词法作用域 📖 1.2 示例 📖 1.3 词法作用域的…

医学专题-多组学在疾病发生发展过程中的研究思路

研究背景 单一组学数据分析通常用来解释某种特征性的生化指标与某些疾病之间的关联,但无法说明其中复杂的因果关系。从疾病表型或某种生物现象出发,寻找影响疾病发生发展的关键因子或通路,借助高通量的技术手段,设置相应的患者组…

49、IDEA 创建类或方法时,实现按格式化 ctrl + alt + l 能变成左花括号在下一行,与右花括号对齐

IDEA 创建类或方法时,左花括号是改成在下一行,与右花括号对齐 默认花括号是这样的 现在想改成这样的 实现按格式化 ctrl alt l 能变成这样 在这里修改就行 把 end of line 改成 next line

基于SSM框架金鱼销售平台源码和论文

基于SSM框架金鱼销售平台源码和论文120 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优…

机器人制作开源方案 | 桌面级全向底盘--本体说明+驱动控制

一、本体说明 1. 底盘概述 该底盘是一款模块化的桌面级应用型底盘,基于应用级软件架构设计、应用级硬件系统设计、典型应用型底盘机械系统设计。 底盘本体为一个采用半独立刚性悬挂的四驱全向底盘。 2. 软件环境介绍 操作系统:Ubuntu18.04系统。基于Deb…

对swap交换分区虚拟内存的理解

Swap分区的作用是什么 更新:2023-05-31 13:10 Swap是一种虚拟内存技术,在计算机内存不足时,它可以将运行中的程序或者数据存到硬盘上以释放内存空间。Swap技术不仅适用于Linux操作系统,Windows和Mac OS也有类似的技术&#xff0…

为什么各个企业都在强调要建立sop?

在现代社会中,随着科技的不断发展,各行各业的竞争也越来越激烈。为了提高工作效率,很多企业开始重视建立标准操作流程(SOP)。那么,为什么要建立SOP呢? 所谓SOP,就是 Standard Opera…

安装ArcGis时需要安装Micsoft.Net Framework 3.5 sp1

在安转ArcGis时遇到一个问题,解决方法如下 下载.Net 按照他的说明 将地址复制到迅雷中下载,并安装 就可以了 安装就可以了

MES系统在电力装备方面的应用

MES系统主要功能:解决“如何生产”的问题 通过实施MES系统,可以贯通从采购到售后服务的全制造流程,透明化生产现场运作,大大提升了生产制造各部门的管理实时性和有效性。 可获得的效益大致如下: 降低不良率&#xff…

【webrtc】接收/发送的rtp包、编解码的VCM包、CopyOnWriteBuffer

收到的rtp包RtpPacketReceived 经过RtpDepacketizer 解析后变为ParsedPayloadRtpPacketReceived 分配内存,执行memcpy拷贝:然后把 RtpPacketReceived 给到OnRtpPacket 传递:uint8_t* media_payload = media_packet.AllocatePayload(rtx_payload.size());RTC

Python break 语句

Python break语句,就像在C语言中,打破了最小封闭for或while循环。 break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。 break语句用在while和for循环中。 如果您使用嵌套循环…

关于JDK 8的HashMap

HashMap 简介 HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。 HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个 JDK1.8…

信号浪涌保护器防雷接地工程应用方案

信号浪涌保护器是一种用于保护电子设备免受电力线路上的瞬时过电压或过电流的装置。信号浪涌保护器的参数方案和应用施工主要取决于信号线路的类型、电气特性、工作环境和保护要求。下面是一篇关于信号浪涌保护器的文章,介绍了一些常见的信号浪涌保护器参数方案和应…

Android Canvas的使用

android.graphics.Canvas 一般在自定义View中,重写 onDraw(Canvas canvas) 方法时用到。 /*** Implement this to do your drawing.** param canvas the canvas on which the background will be drawn*/Overrideprotected void onDraw(Canvas canvas) {super.onDra…

LeetCode 剑指 Offer 10- I. 斐波那契数列

LeetCode 剑指 Offer 10- I. 斐波那契数列 题目描述 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下: F(0) 0, F(1) 1 F(N) F(N - 1) F(N - …

LeetCode 46题:全排列

题目 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2: 输入:…

Bridge Champ举办人机对战赛:NFT游戏与传统竞技共生发展编织新格局

概要 现在,NFT与体育竞技正日益紧密地联系在一起。一些体育项目开始推出与赛事或球队相关的NFT,同时也有部分NFT游戏开始举办电子竞技赛事。这种共生发展正在改变体育竞技的生态。 笔者采访了桥牌冠军项目相关负责人,探讨NFT游戏与传统体育竞技的融合潜力。桥牌冠军近期成功举…

您必须尝试的 4 种经典特征提取技术!

一、说明 特征提取如何实现?其手段并不是很多,有四个基本方法,作为AI工程师不能不知。因此,本篇将对四种特征提取给出系统的方法。 二、概述 图像分类长期以来一直是计算机视觉领域的热门话题,并希望能够保持这种状态。…

MES系统质量检查:提升制造业生产质量

一、MES系统质量检查的定义: MES系统质量检查是指制造执行系统中的质量管理模块,旨在监控和管理生产过程中的质量控制和质量检查活动。该模块涵盖了产品质量数据的采集、分析、报告和追溯等功能,以确保产品符合质量要求,并提供实…