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

news2024/11/26 10:46:03

从内存图来理解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对象同时存在。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++/嵌入式笔试面试八股】二、24.TCP三次握手四次挥手 | TCP可靠性

TCP三次握手四次挥手 64.TCP头部中有哪些信息?❤️ TCP数据报格式(左图) UDP数据报格式也放这(右图),不具体解释了。 结合三次握手四次挥手来看 端口: 区分应用层的不同应用进程 扩展:应用程序的端口号和应用程序所在主机的 IP 地址统称为 socket(套接字),IP:端口…

Linux - 安装nacos 2.1.0

安装包下载 网址为 https://github.com/alibaba/nacos/tags 点击访问 本人选择的nacos版本为2.1.0 与之对应的spring代码版本为 <spring.boot.version>2.3.12.RELEASE</spring.boot.version> <spring.cloud.version>Hoxton.SR12</spring.cloud.version…

运输层(TCP运输协议相关)

运输层 1. 运输层概述2. 端口号3. 运输层复用和分用4. 应用层常见协议使用的运输层熟知端口号5. TCP协议对比UDP协议6. TCP的流量控制7. TCP的拥塞控制7.1 慢开始算法、拥塞避免算法7.2 快重传算法7.3 快恢复算法 8. TCP超时重传时间的选择8.1 超时重传时间计算 9. TCP可靠传输…

如何在vscode中debug python代码,包括如何优雅地传入多个参数

Visiul Studio Code, 简称vscode&#xff0c;是一款轻量级代码编辑器&#xff0c;其丰富的扩展程序使得其可以方便地作为任何语言的编辑器。 本文将讲述如何在vscode中对python脚本文件进行debug。 本文主要包括debug的两种方式&#xff1a; 基本debugging(basic debugging)…

咖啡店小程序怎么做

咖啡店小程序功能介绍 咖啡店小程序是一款专为咖啡店打造的移动应用程序&#xff0c;旨在提供更便利、高效的服务体验。以下是该小程序的主要功能介绍&#xff1a; 1. 菜单浏览&#xff1a;用户可以通过小程序浏览咖啡店提供的各种咖啡、茶和小吃菜单&#xff0c;包括详细的产…

Docker基础——Centos7安装Docker

0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…

速通sklearn库

速通sklearn库 前言 ​ 最近在复习之前学习过的知识点&#xff0c;因此想到把学过的总结一下&#xff0c;方便后面再次复习&#xff0c;所以有了这个系列。 说明 ​ 由于标题写的是“速通”&#xff0c;因此我的想法是可以让大家看完这篇文章&#xff0c;可以上手matplotlib库&…

FCPX插件-复古老电影胶片边框幻灯片照片展示介绍动画 Emotion Slides

Emotion Slides是一款fcpx插件&#xff0c;可以制作复古老电影胶片边框幻灯片照片展示介绍动画&#xff0c;完全自定义任意数量的场景&#xff0c;完全定制的控制器&#xff0c;7个独特的场景准备&#xff0c;易使用简单&#xff0c;只需拖放。 Emotion Slides插件的主要功能包…

【网络编程】传输层协议——UDP协议

文章目录 一、传输层的意义二、端口号2.1 五元组标识一个通信2.2 端口号范围划分2.3 知名端口号2.4 绑定端口号数目问题2.5 pidof & netstat命令 三、UDP协议3.1 UDP协议格式3.2 如何理解报头&#xff1f;3.3 UDP协议的特点3.4 UDP缓冲区3.5 UDP传输最大长度 一、传输层的意…

基于linux下的高并发服务器开发(第一章)- GDB调试(1)1.13

掌握一个清屏快捷键&#xff1a;CTRLL 01 / 什么是GDB 02 / 准备工作 03 / GDB 命令 -- 启动、退出、查看代码 在~/Linux/lesson08目录下有test.c文件 #include <stdio.h> #include <stdlib.h>int test(int a);int main(int argc,char* argv[]){int a,b;printf(&…

React懒加载/动态加载(Suspense +lazy())简单实例

页面嵌套 两种页面嵌套的方式&#xff0c;一种是父子组件&#xff0c;一种是懒加载1、父子组件&#xff08;可略&#xff0c;只用来做例子对比&#xff09;2、使用懒加载 两种页面嵌套的方式&#xff0c;一种是父子组件&#xff0c;一种是懒加载 1、原本需要用父子组件来实现页…

计算机网络 day7 扫描IP脚本 - 路由器 - ping某网址的过程

目录 network 和 NetworkManager关系&#xff1a; 实验&#xff1a;编写一个扫描脚本&#xff0c;知道本局域网里哪些ip在使用&#xff0c;哪些没有使用&#xff1f; 使用的ip对应的mac地址都要显示出来 计算机程序执行的两种不同方式&#xff1a; shell语言编写扫描脚本 思…

selenium WebDriver 中的几种等待--sleep(),implicitly_wait(),WebDriverWait()

目录 强制等待:sleep() 隐式等待:implicitly_wait() 显示等待:WebDriverWait() 与until()或者until_not()方法结合使用 WebDriverWait与expected_conditions结合使用 显示等待,自定义等待条件 强制等待:sleep() import time sleep(5) #等待5秒 设置固定休眠时间&#x…

【JAVA】与数字相关的类,Number Math 类

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言数据类型Number类介绍数据格式化实例 Math类介绍静态常量实例 前言 为了解决对数字、日期和系统设置进行处理的困难&#xff0c;如&#xff1a;一些数字&数学问题、随机…

【iOS】—— 编译链接

【iOS】—— 编译链接 文章目录 【iOS】—— 编译链接编译流程预处理&#xff08;预编译Prepressing&#xff09;编译&#xff08;Compilation&#xff09;汇编&#xff08;Assembly&#xff09;链接&#xff08;Linking&#xff09; 编译流程 编译流程分为四步 预处理&#…

基于mediapipe的手势识别

安装opencv:pip install opencv-python 安装mediapipe:pip install mediapipe draw_utils.py: import cv2 import numpy as npdef draw_line(img, width, height, hand, start_index, stop_index):for i in range(start_index, stop_index):x1, y1 = int(hand.landma…

Unity 多相机 同屏显示

一 首先了解&#xff1a; 相机和Canvas 的渲染先后关系 什么是相机的渲染顺序&#xff1f; 答&#xff1a;简单理解就是 用毛刷 刷墙面&#xff0c;先刷的&#xff0c;会被后刷的 挡住 。 列如&#xff1a;相机01&#xff1a; 先渲染的大海&#xff0c;相机02&#xff1a;后…

爬虫之Scrapy

一 介绍 Scrapy一个开源和协作的框架&#xff0c;其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的&#xff0c;使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛&#xff0c;可用于如数据挖掘、监测和自动化测试等领域&#x…

jquery实现甘特图时效管理

一、效果图 二、html文件 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html lang"en"><head><script src"../../../baoBiaoHtml/js/jquery-1.9.0.js"></script><script src"../..…

【GitOps系列】自动化构建Image

文章目录 使用 GitHub Action 构建镜像使用 GitLab CI 构建镜像使用 Tekton 构建镜像Tekton组件安装Tekton 简介创建 Tekton Pipeline创建 Task创建 Pipeline创建 EventListener创建 TriggerTemplate创建 Service Account 和 PVC设置 Secret 创建 GitHub Webhook触发 Pipeline …