JAVA-初步认识-第十二章-JVM中的多线程分析

一.

我们学java程序学到现在,到底是多线程的,还是单线程的?(现实中多线程是一直存在的,我们只是才开始学习这个概念而已,没学过不代表不存在。)

虚拟机的启动本身就依赖了多条线程,为什么?

举例来看,(举实例来研究多线程)

New了三个匿名对象,画一个堆内存演示一下。

左边是栈,右边是堆。栈里面有主函数,主函数里有代码。堆里面开始创建对象,匿名对象一创建完就是垃圾了(没有指向),现在有三个垃圾。

主函数里面代码有很多,它继续在执行。

从这里面立刻就可以得到第一点,就是我们的java虚拟机在运行的时候肯定有一条线程是在执行主函数的。这是必须的,没有这个线程,主函数根本无法运行。有人说,不是虚拟机调用主函数的么?再怎么调用,都要依赖线程来执行,因为只有线程才能执行代码。其中有一条线程是负责主线程执行的。(调用函数完全是编程语言,线程则有点涉及硬件了)

在堆内存中出现了垃圾,需要回收。如果出现了回收的动作,有人说主线程来执行垃圾的回收,那也就意味着程序运行到一半停止了,主函数去执行垃圾的回收了。这不对,垃圾的回收我们是看不着的。

主线程执行的过程中,垃圾回收器会不定时地来回收这个垃圾,意味着有人在做这个回收的动作,这就代表着有两个线程。其实不止两个,有很多线程,没有必要一一介绍。虚拟机底层它有开启多线程需要去做的任务,只不过这条任务我们可以分析地出来(这条任务就是主函数运行,垃圾回收)。→虚拟机在程序运行过程中貌似很重要。

本身虚拟机的启动,线程就不止一个。专门处理垃圾回收的线程我们称之为垃圾回收线程,在主函数中执行代码的线程称之为主线程。

任何一个线程启动后,都有它们自己的任务。

垃圾回收线程的内容,或者说任务代码都在垃圾回收器内部定义呢,我们不用管,它本身是在内部自动运行的,不需要我们去执行它。

对于垃圾回收装置,我们做一个简单地演示,是怎么回收的。这是底层内部完成的。

怎么演示呢?试想一下,堆内存中会产生很多对象,每个对象都具备着被回收的可能。对象怎么被回收的,只有对象自己最清楚。对象创建完以后,每个对象都有自己的执行特点,它怎么被回收,它自己最清楚,每个对象都具备着被回收的方法。写对象的时候,调用这个方法么?没有,每个对象都具备的方法在object类中。

这个方法就是finalize,如果不需要配置系统资源或执行其他清除,就不用重写finalize方法。(finalize就是回收)

现在验证一下,finalize方法到底是怎么一回事。

其实根本不用复写,因为它不需要做这个事情,它里面产生对象并没有做太多封装数据,直接把内存清除掉就完事了,跟我们栈内存释放原理,清除内存空间把数据抹去,存储其它数据就完事了。只有涉及到系统资源的,才会去进行finalize的定义以及关闭系统资源。

DOS的运行结果没有demo ok。

我们知道这三个匿名对象是变成垃圾了,但是它们立刻就被回收了吗?不一定,它们在不定时的时间里回收。

什么是垃圾回收器呢?就是垃圾回收的那个程序。这程序在做垃圾回收的动作,这程序在被单独的一个线程负责执行。如果找到这个垃圾回收器。

系统类里面有一个gc方法。这个方法可以运行垃圾回收器。通过这个系统类的静态方法来运行垃圾回收器。

截图中的gc不是立刻让垃圾回收器启动,是在告诉垃圾回收器你要启动,至于怎么启动它说了算的。

为什么hello world先输出了?按理说,垃圾回收器启动了,它会回收两个垃圾吧,一收的时候就调用了这个对象的finalize方法。说了嘛,垃圾回收器会调用finalize方法,一打印说明有垃圾被回收掉了。

(gc方法启动垃圾回收器,垃圾回收器启用finalize方法,真正起到回收作用的是finalize)

为什么hello world会在demo ok前面打印呢?因为这是两个线程完成的。主线程调用到gc的时候,这个时候就在告诉垃圾回收器。垃圾回收器就会在不定时启动机器,同时主线程继续往下运行,而垃圾回收线程独立于主线程操作。在主线程打印了hello world后,垃圾处理

器才处理了两个垃圾对象。

修改一下程序,再看结果

编译运行多次后,出现了两种DOS结果。这里面两个概念,一个是slime,一个是优先级。现在先不谈技术,先讨论一下现象。

除了上面两种情况外,还有可能出现demo ok先出来的情况。

上图的这种情况是,垃圾回收器刚回收了一个,虚拟机就结束了。虚拟机结束的话,它会强制地结束它所在的进程(就是内存区域),就是java.exe程序被结束进程了,内存就都被清除了。因此,还没等调用finalize就结束了。(整个虚拟机都结束了,更何况里面的垃圾回收线程)

上面的例子验证出来,至少有两个线程。

其实还有一个线程,主线程执行完以后,这些代码都结束了。线程的任务只要一结束,线程就结束了,也就意味着主线程结束了。有人说主线程都结束了,虚拟机还搞什么?hello world都打印完了,虚拟机应该退出。告诉你,仅仅是主线程结束了,虚拟机中的其他线程还在执行,虚拟机还没结束呢。

总结:虚拟机当中所涉及的多线程内容。

时间: 2024-10-11 18:20:57

JAVA-初步认识-第十二章-JVM中的多线程分析的相关文章

perl5 第十二章 Perl5中的引用/指针

第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用  子程序模板七.数组与子程序八.文件句柄的引用 一.引用简介    引用就是指针,可以指向变量.数组.哈希表(也叫关联数组)甚至子程序.Pascal或C程序员应该对引用(即指针)的概念很熟悉,引用就是某值的地址,对其的使用则取决于程序员和语言的规定.在Perl中,可以把引用称为指针,二者是通用的,无差别的.引用在创建复杂数据方面十分有用

Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门 Java提供的三大类网络功能: (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置.利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端. (2)Socket:又称"套接字",用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务).在客户/服务器网络中,当客

Java编程思想---第十二章 通过异常处理错误(中)

第十二章  通过异常处理错误(中) 12.4 创建自定义异常 我们不必拘泥于Java中已有的异常类型,Java提供的异常体系不可能预见所有的错误,所以可以自己定义异常类来表示程序中可能会遇到的特定问题:要自己定义异常类,必须从已有的异常类继承,最好是选择意思相近的异常类继承,建立新的异常类最简单的方法就是让编译器为你产生默认构造器,所以这几乎不用写多少代码: class SimpleException extends Exception { } public class InheritingEx

java 面向对象编程 --第十二章 JDK常用类

1.  系统类 java.lang包   System类 sys.out;sys.exit;sys.gc; sys.currentTimeMillis();----得到从1970-01-01到当前时间的毫秒数,long型 sys.getProperties();&sys.getProperty();user.dir确定&得到当前工程的工作目录,String型 2.  日期类 java.util包     Date类 @Deprecated——> 方法前加上该注解,表示该方法已过时,有

Java 第十二章 继承 笔记

Java 第十二章  继承 笔记 一.使用继承:     1)方便修改代码     2)减少代码量 二.super 继承object 类:super 访问父类的无参构造:super 指的是object 的无参构造.     例:子类调用父类:super.属性 / super.方法    注意:子类不能继承父类私有属性:得用set.get方法来调用:    super只能写在代码块的第一句:super只能调用非私有的方法:    super只能出现在子类的方法和构造方法中. 三.不能被继承的父类成

疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程java任务timerstring 2009-01-16 21:12 6722人阅读 评论(0) 收藏 举报  分类: J2SE(63)  版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天讲了Swing基本的控件,今天开始讲特殊控件.一天讲2个吧,首先讲用JProgressBar,Pro

Java(第十二章)

第十二章 一.变量的作用域(有效的使用范围) 1.变量有2种 1.1成员变量(属性) 声明在类的里面,方法的外面 1.2 局部变量 声明在方法里面或for循环结构中 2.调用时的注意事项(初始值不同.作用域不同) 2.1 成员变量,有默认值 在当前类直接通过成员变量名调用:在其他类中,通过该类的对象名.属性(成员变量)名调用:成员变量名称在同一个类中是唯一的. 2.2 局部变量,没有默认值,必须先赋值再使用 局部变量,只能在当前的方法中使用,其他方法和其他类不能调用:在同一个方法中名称是唯一的,

“全栈2019”Java第二十二章:控制流程语句中的决策语句if-else

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第二十二章:控制流程语句中的决策语句if-else 下一章 "全栈2019"Java第二十三章:流程控制语句中决策语句switch上篇 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf

“全栈2019”Java第九十二章:外部类与内部类成员覆盖详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第九十二章:外部类与内部类成员覆盖详解 下一章 "全栈2019"Java第九十三章:内部类应用场景(迭代器设计模式) 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"