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

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

一、内存图简介

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

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

首先定义一个Person类。

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

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

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

再定义一个测试类

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

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

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

二、单线程代码执行方式

启动Test类之后,开辟一个主线程栈,创建一个person1对象(储存在堆内存中且只携带类中的非静态成员)
【并发编程的艺术读书笔记】从内存图来理解java是如何执行多线程的_第4张图片

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

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

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

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

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

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

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();
	}
}

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

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

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

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

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

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

你可能感兴趣的:(并发编程,并发编程的艺术,内存图,juc,java)