一.
我们学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都打印完了,虚拟机应该退出。告诉你,仅仅是主线程结束了,虚拟机中的其他线程还在执行,虚拟机还没结束呢。
总结:虚拟机当中所涉及的多线程内容。