【并发编程的艺术读书笔记】从内存图来理解java是如何执行多线程的

从内存图来理解java是如何执行多线程的

一、内存图简介

众所周知,java类中的成员变量会保存到方法区、java运行时的方法会存入栈中,随之方法中的局部变量也是存储在栈中的,引用类型(new出来的对象)存储在堆内存中。下面用java内存中的方法区、栈内存、堆内存来演示java方法的执行过程。

在这里插入图片描述

首先定义一个Person类。

public class Person {
    
    
    public int age;
    public String name;
    
	public void m1() {
    
    
	}
	public void m2() {
    
    
		m3();
	}
	public void m3() {
    
    
	}
	
	public static void m4() {
    
    
	}
}

此时我们的内存图中是这样的

在这里插入图片描述

再定义一个测试类

public class Test {
    
    
	public static void main(String[] args) throws Exception{
    
    
		Person person1 = new Person();
		person1.m1();
	}
}

此时我们的内存图中是这样的

在这里插入图片描述

二、单线程代码执行方式

启动Test类之后,开辟一个主线程栈,创建一个person1对象(储存在堆内存中且只携带类中的非静态成员)
在这里插入图片描述

随后person1对象调用m1方法,主线程栈从堆内存中的person1对象的地址中拷贝一份m1方法入栈

在这里插入图片描述

待m1执行完后,m1方法出栈,整个主线程的内容结束,方法依次出栈,创建的对象引用被销毁。

在这里插入图片描述

而堆内存中的person1对象如果没有在其他地方被引用,将会被回收。

在这里插入图片描述

main方法执行完毕

三、多线程代码执行方式

对Test类进行调整,让他有多个线程参与

public class Test {
    
    
	public static void main(String[] args) throws Exception{
    
    
		Thread thread1 = new Thread() {
    
    
			@Override
			public void run() {
    
    
				Person person1 = new Person();
				person1.m2();
			}
		};
		Thread thread2 = new Thread() {
    
    
			@Override
			public void run() {
    
    
				Person person1 = new Person();
				person1.m3();
			}
		};
		// -----------------------

		thread1.start();
		thread2.start();
		
		Person person1 = new Person();
		person1.m1();
	}
}

执行到分割线时内存图如下所示

在这里插入图片描述

随后执行start方法将线程丢入就绪队列

在这里插入图片描述

由于线程1、2均进入就绪态。cpu随时可能分配时间片使其运行所以thread1、thread2中创建person1以及主线程中创建person1对象的先后顺序无法确定。可能在主线程中person1的对象已经执行完方法后被回收了thread1、2才开始创建,也可能三个person1对象同时存在。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_51383106/article/details/131678878