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

Java多线程 V1

启动一个软件就相当于启动了一个进程,对于Java程序来说,启动的就是Java虚拟机(JVM)这个进程。

JVM进程启动后,会先启动主线程,主线程由JVM启动,它的作用是调用main方法,也就是说main方法的运行是在主线程中进行的。同时,JVM还会启动一个垃圾回收线程(GC线程),它就像“保洁员”一样,时刻监控堆内存,当垃圾达到一定程度时就进行清理,释放内存。所以,即便我们没特意提过多线程,Java程序其实一直运行在多线程环境中(主线程+GC线程)。

在main方法执行过程中,程序员可以自己创建线程对象并启动,甚至能启动100个线程,这些操作都可以在main方法里通过编写代码完成,这样Java程序就会处于多线程环境中。

  根据Java虚拟机规范,线程共享的内存部分包括堆、方法区(含运行时常量池),如果Java程序启动了10个线程,它们会共享同一个堆和方法区。    而线程私有的内存部分有程序计数器、虚拟机栈和本地方法栈。每个线程都有自己独立的虚拟机栈,用于存储方法调用时的压栈、弹栈信息;本地方法栈则用于存储带native关键字的方法(底层调用C++动态链接库程序)的相关信息,10个线程就有10个独立的虚拟机栈和本地方法栈。

 

这也决定了不同变量的线程安全性:局部变量存储在虚拟机栈中,因每个线程的虚拟机栈独立,所以局部变量不共享,不存在线程安全问题;实例变量在对象中,对象存于堆里,静态变量也在堆中,二者都处于线程共享的内存区域,所以需要考虑线程安全问题。

 

 

2

 

程序执行时,先创建进程,再在进程中执行程序。一般来说,一个进程可以包含多个线程,线程是进程中的一个执行单元,是进程的一部分,负责在进程中执行程序代码。每个线程都有自己的栈以及程序计数器(以Java为例),并且可以实现进程资源的共享,进程资源共享靠的是堆和方法区。多线程可以在同一时刻执行不同的操作,从而提高程序的执行效率。

现代操作系统支持多进程,也就是可以启动多个软件,一个软件通常就是一个进程,这称为多进程并发。通常一个进程可以启动多个线程,称为多线程并发。除了并发,还有并行的概念,下面具体说明:

- 并行:针对多核CPU,指真正意义上的同时执行。
- 并发:针对单核CPU,多个进程或多个线程之间会抢夺CPU资源,谁抢到谁执行。它们占有CPU的时间线不同,会频繁切换执行,宏观上给人同时执行的错觉,但微观上并非同时。

多线程的作用,严格来说是提高CPU的利用率,让能力很强的CPU多干活。毕竟如果CPU只能每时每刻支持一个软件运行,会造成浪费,而多线程能让CPU同时处理多个软件,给人同时执行的感觉。

在相关规范中,存放区是线程共享的,而栈、程序计数器是每个线程私有的,这些运行原理前面已提及。

还有“main thread”即主线程,主线程负责执行main方法。除了主线程,还会启动垃圾回收线程,因此启动Java虚拟机至少会启动两个线程,可能还有其他未知线程。在main方法执行过程中,程序员可以手动创建并启动其他线程,这些线程属于分支线程。

再详细说说并发与并行:

- 并发是单核CPU中,同一时刻只能有一条指令执行,但多个指令被快速轮换执行,宏观上有同时执行的效果,微观上是把时间分成若干段,让多个指令快速交替执行。
- 并行是多核CPU中,同一时刻多条指令在多个CPU上同时执行,多个线程或进程能独立、同时、互不干扰地执行,不存在抢夺CPU的情况。

我们用Java写的程序,可能属于并发编程,也可能属于并行编程,或者两者都有,这取决于CPU的使用情况。如果电脑是多核但启动软件太多,可能是并发;如果多核CPU都空闲,可能是并行。所以现在的编程中,并发和并行通常是同时存在的。

关于线程的调度模型,有两种:

- 分时调度:所有线程轮流使用CPU执行权,平均分配每个线程占有的CPU时间,强调公平。
- 抢占式调度:里面有优先级的概念,优先级高的线程更能抢到CPU时间片或更容易拿到执行权,以较大的概率优先获得CPU资源;如果线程优先级相同,会随机选择一个线程获得CPU执行权。Java采用的就是抢占式调度模型。

那么在Java语言中,实现线程的方式也是比较清晰的。

 

http://www.dtcms.com/a/273339.html

相关文章:

  • AIStarter 3.2.0正式上线!高速下载+离线导入+一键卸载新功能详解【附完整使用教程】✅ 帖子正文(字数:约 400 字)
  • 静态路由综合实验
  • WiFi技术深度研究报告:从基础原理到组网应用与未来演进
  • python+django/flask基于微信小程序的农产品管理与销售APP系统
  • CTFshow-PWN-栈溢出(pwn62-pwn64)
  • JAVA面试宝典 -《新潮技术:协程与响应式编程实践》
  • 【Ubuntu】编译sentencepiece库
  • next.js打包后的前端资源如何进行部署和访问,为什么没有index.html
  • Vue响应式原理六:Vue3响应式原理
  • Java 17 新特性解析:密封类与模式匹配的完美协作
  • 01背包问题总结
  • 三维旋转沿轴分解
  • AWS ECS任务角色一致性检查与自动修复工具完全指南
  • LVGL学习笔记-----进度条控件(lv_bar)
  • Java结构型模式---桥接模式
  • 什么?不知道 MyBatisPlus 多数据源(动态数据源)干什么的,怎么使用,看这篇文章就够了。
  • AI探索 | 豆包智能助手跟扣子空间(AI办公助手)有什么区别
  • Ranger框架的发展历程
  • Windows系统DLL、运行库、DirectX等DLL丢失等异常状态
  • 数组的应用示例
  • 【Python进阶篇 面向对象程序设计(7) Python操作数据库】
  • 《测试开发:从技术角度提升测试效率与质量》
  • 《Revisiting Generative Replay for Class Incremental Object Detection》阅读笔记
  • 3D lidar目标跟踪
  • PyTorch自动微分:从基础到实战
  • Linux C 文件基本操作
  • 【Java并发编程】AQS(AbstractQueuedSynchronizer)抽象同步器核心原理
  • 飞算科技:以原创技术赋能电商企业数字化转型
  • AI翻唱——So-VITS-SVC
  • ubuntu virtual box全屏