当前位置: 首页 > news >正文

Java与GO语言对比分析

你是不是总听到go与java种种对比,其中在高并发的服务器端应用场景会有人推荐你使用go而不是 java。
那我们就从两者运行原理和基本并发设计来对比分析,看看到底怎么回事。

运行原理对比

java

java 中 jdk 已经帮我们屏蔽操作系统区别。
只要我们下载并配置好 jdk,我们就能执行java 文件了。

在这里插入图片描述

go

go tool 中使用 go build 就能将 go 代码编译生成对应操作系统的可执行文件,可以直接运行。

在这里插入图片描述

跨平台实现原理

java

我们会在不同操作系统下,去下载适配对应操作系统的 jdk。实现我们一次编写,任意运行在各个操作系统的 JVM上。

在这里插入图片描述

go

编写go 代码后,我们利用 go tools 中编译器指定要执行的操作系统进行 build。 生成一个平台相关的可执行文件(在 Windows 上是 .exe 文件,在 Linux 或 macOS 上通常是没有扩展名的二进制文件)

在这里插入图片描述

并发对比

java

线程的生命周期
假设客户端每提交一个任务,需要单独 java 线程处理,会有如下流程。

  1. java中创建Thread对象(用户态)
  2. 在操作系统内核创建一个Thread(内核态)
  3. 由操作系统调度对应内核线程
    操作系统调度Thread(内核态)抢占cpu核心
    cpu核心执行Thread(内核态)的机器指令集合
    cpu执行任务结束
  4. 销毁Thread(内核态)
  5. 销毁Thread(用户态)

在这里插入图片描述

其实不难发现,java 线程模型其实比较偷懒···。对的,它基本没干啥,直接和一个操作系统的线程绑定(1 对 1),这样java 就不用考虑线程调度管理了,操作系统会调度运行线程。

池化操作
当然作为一名优秀的java开发,如果按照上述那样使用线程,当有客户端足够多,也就是所谓高并发情况下,java 线程模型就会导致服务崩溃,是的你没有听错,崩溃宕机。
所以优秀 java开发常常不会‘裸’使用thread,会将使用线程池技术将线程进行池化保存,让线程能够复用。

池化的初始化流程
1.java中初始化4个Thread对象(用户态)
2.操作系统内核中初始化4个Thread(内核态)
3.客户端提交线程任务到任务队列
4.线程池中线程从任务队列中消费任务(内核Thread-就绪态)
5.由操作系统调度对应内核线程

池化后流程:
1.客户端提交线程任务到任务队列
2.线程池中线程从任务队列中消费任务(内核Thread-就绪态)
2.由操作系统调度对应内核线程

ps:至于线程池详细学习,这里就不介绍了。

在这里插入图片描述

go

来吧让我们了解了解go的并发模型(MPG)吧。

ps:这里参考 《Go 并发编程实战》,想要详细了解MPG实现细节可以看这本书。

在这里插入图片描述

G:goroutine缩写。每一个并发执行的活动称为G
P:processor的缩写。一个P代表执行一个Go代码片段所必需的资源(或称“上下文环境”)
M:machine的缩写。一个M代表一个内核线程

运行流程
1.go 接受并发任务封装 G
2.寻找合适p并放入 p 中(p 中存在列表 保存待执行 G)
3.p 与某个 M (空闲或新创建)进行关联
4.创建一个内核线程与 M 对应
5.由操作系统调度对应内核线程

对比分析

我本身java开发,当我了解 MPG 模型我就感觉,其实和 java 线程池执行并行任务大差不差。都是池化固定几个内核线程并发执行应用层面提交的任务。就是达到了线程复用,省去频繁创建销毁的操作。

那是不是 java 线程池可以和 MPG 并发模型相媲美呢?

随着我深入了解发现并不是这样的。仔细想一下 java 线程池怎么使用,是在一个业务中我们需要频繁的创建和销毁线程,然后我们创建一个线程池给这个业务使用

是的,这个线程池这是这个业务局部使用的。但是 java 其他业务如果没使用线程池直接使用线程并发,或者thread-per-request style(每个请求启动一个线程) 都会造成java 应用中会存在很多没有池化线程。

  • 未池化线程较多,还是存在很多线程创建和销毁。
  • 应用中存在较多线程会导致竞争比较激烈,线程阻塞,线程唤醒,切换线程这种,也会频繁的进行线程内核态上下文切换。

相比于 java,go 则是全局模型,也就是说整个 go 应用的 M 都是复用的,创建和销毁频率会非常小。而且在理想情况,能实现一个核心对应一个线程,无需资源竞争。另外就是,在并发业务编写场景下,go 是如此丝滑且高效····

java 就当真不行了吗?

java 线程模型虽然笨重但也有自己优势。

  • 复杂的线程上下文代表功能很多,例如 threadLocal,让我们更加便捷实现一些业务功能(用户信息,鉴权相关功能都能利用到)。
  • 此外,我对比的是过时的 java8。在 java 新版本中也已经实现了类似goroutines的用户态线程,java称作virtual threads有兴趣的可以看看,下篇就分享这个。

结语

这篇文章比较基础,但又需要你了解 java 相关的并发知识。希望通过图示,以及对比分析能让你了解到 java 和 go 的区别。

有任何问题欢迎留言指正哦。

相关文章:

Java与GO语言对比分析

你是不是总听到go与java种种对比,其中在高并发的服务器端应用场景会有人推荐你使用go而不是 java。 那我们就从两者运行原理和基本并发设计来对比分析,看看到底怎么回事。 运行原理对比 java java 中 jdk 已经帮我们屏蔽操作系统区别。 只要我们下载并…...

Linux文件系统原理

Linux文件系统 冯诺依曼在1945年提出计算机的五大组成部分 运算器:CPU 控制器:CPU 存储器:内存和硬盘 输入设备:鼠标、硬盘 输出设备:显示器一、硬盘结构 机械硬盘结构 扇区:硬盘的最小存储单位&#xff…...

初识Spring Cache:如何简化你的缓存处理?

文章目录 1、Spring Cache介绍2、 常用注解3、 使用案例 1、Spring Cache介绍 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,底层可以切换不同的…...

攻防世界[GoodRe]

攻防世界[GoodRe] 学到知识: 逆向的精髓:三分懂,七分蒙。TEA 算法快速识别(蒙): 数据处理的形式:进入加密时的数据和加密结束后的数据,处理时数据的分组等等,都能用来…...

IntelliJ IDEA实用插件:轻松生成时序图和类图

IntelliJ IDEA生成时序图、类图 一、SequenceDiagram1.1 插件安装1.2 插件设置1.3 生成时序图 二、PlantUML Integration2.1 插件安装2.2 插件设置2.3 生成类图 在软件建模课程的学习中,大家学习过多种图形表示方法,这些图形主要用于软件产品设计。在传统…...

SpringBoot + Mybatis-Plus中乐观锁实现

悲观锁 悲观锁是一种悲观思想,它认为数据很可能会被别人所修改 所以总会对数据进行上锁,读操作和写操作都会上锁,性能较低,使用较少! 乐观锁 乐观锁是一种乐观思想,它认为数据并不一定会被别人所修改 所以…...

设计模式深度解析:分布式与中心化,IT界两大巨头“华山论剑”

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 ✨IT界的两大巨头交锋✨ 👋 在IT界的广阔天地中,有两座…...

转行一年了

关注、星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 来公司一年了。 说是转行其实还是在半导体行业,熟悉我的朋友知道 ,我在18年开始进入半导体行业,那个时候想着行业很重要,站对了…...

【LeetCode 151】反转字符串中的单词

1. 题目 2. 分析 这题要是用Python写,就非常简单了。 3. 代码 class Solution:def reverseWords(self, s: str) -> str:s " ".join(reversed(s.strip().split()))return s...

Behind the Code:Polkadot 如何重塑 Web3 未来

2024 年 5 月 17 日 Polkadot 生态 Behind the Code 第二季第一集 《创造 Web3 的未来》正式上线。第一集深入探讨了 Polkadot 和 Web3 技术在解决数字身份、数据所有权和去中心化治理方面的巨大潜力。 🔍 查看完整视频: https://youtu.be/_gP-M5nUidc?…...

for循环里如果std::pair的类型写不对,可能会造成性能损失

第一版 std::map<int, int> t;t.emplace(1, 1);for (const std::pair<int,int>& data : t){int i 0;std::ignore i;}中间留一些空格&#xff0c;是因为ms在调试的时候&#xff0c;尤其是模板比较多的时候&#xff0c;经常断点的行号有问题。比如第5行的断点&…...

【Linux】Linux的基本指令_2

文章目录 二、基本指令8. man9. nano 和 cat10. cp11. mv12. echo 和 > 和 >> 和 <13. more 和 less14. head 和 tail 和 | 未完待续 二、基本指令 8. man Linux的命令有很多参数&#xff0c;我们不可能全记住&#xff0c;我们可以通过查看联机手册获取帮助。访问…...

Effective C++(3)

3.资源管理 条款13&#xff1a;以对象管理资源 以对象管理资源对于传统的堆资源管理&#xff0c;我们需要使用成对的new和delete&#xff0c;这样若忘记delete就会造成内存泄露。因此&#xff0c;我们应尽可能以对象管理资源&#xff0c;并采用RAII&#xff08;Resource Acqu…...

自定义RedisTemplate序列化器

大纲 RedisSerializerFastJsonRedisSerializer自定义二进制序列化器总结代码 在《RedisTemplate保存二进制数据的方法》一文中&#xff0c;我们将Java对象通过《使用java.io库序列化Java对象》中介绍的方法转换为二进制数组&#xff0c;然后保存到Redis中。实际可以通过定制Red…...

Flutter 中的 CupertinoContextMenuAction 小部件:全面指南

Flutter 中的 CupertinoContextMenuAction 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;CupertinoContextMenuAction 是一个专门用于构建 iOS 风格的上下文菜单选项的组件。它为用户提供了一种便捷的方式来执行与特定项目相关的操作&#xff0c;例如在列表项上长按可…...

Element-Ul快速入门

引言 Element UI是一个vue.js的桌面UI库。它提供了一套丰富、灵活和实用的UI组件&#xff0c;使开发者能以最少的时间和代码量完成复杂的界面设计。本文将会介明如何快速上手Element UI。 安装和基本使用 首先&#xff0c;你需要在你的项目中安装Element UI。如果你已经安装…...

Django的模型层——2模型实例

1. 类的属性 objects&#xff1a;是Manager类型的对象&#xff0c;用于与数据库进行交互 当定义模型类时没有指定管理器&#xff0c;则Django会为模型类提供一个名为objects的管理器 支持明确指定模型类的管理器 class BookInfo(models.Model):...books models.Manager()当为…...

Python筑基之旅-MySQL数据库(四)

目录 一、数据表操作 1、新增记录 1-1、用mysql-connector-python库 1-2、用PyMySQL库 1-3、用PeeWee库 1-4、用SQLAlchemy库 2、删除记录 2-1、用mysql-connector-python库 2-2、用PyMySQL库 2-3、用PeeWee库 2-4、用SQLAlchemy库 3、修改记录 3-1、用mysql-conn…...

OceanBase SQL 诊断和调优实践——【DBA从入门到实践】第七期

数据库作为绝大多数应用系统储存数据的核心系统&#xff0c;在用户系统需要访问数据时&#xff0c;有着至关重要的作用。在这些交互中&#xff0c;SQL 语言是应用与数据库系统之间“沟通”的桥梁&#xff0c;它负责将应用的指令传达给数据库。因此&#xff0c;SQL 的性能好坏直…...

C++之std::is_trivially_copyable(平凡可复制类型检测)

目录 1.C基础回顾 1.1.平凡类型 1.2.平凡可复制类型 1.3.标准布局类型 2.std::is_trivially_copyable 2.1.定义 2.2.使用 2.3.总结 1.C基础回顾 在C11中&#xff0c;平凡类型&#xff08;Trivial Type&#xff09;、平凡可复制类型&#xff08;TrivialCopyable&#x…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...