Java并发--内存结构图及线程安全

news2025/5/24 16:58:43

内存结构图

内存-> (开辟的数组) -> (方法区,堆,栈,程序计数器,本地方法栈)

img

:几乎所有的对象实例都在这里分配内存。堆中每个对象的头信息都标属着他属于哪个类。

方法区它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据

的区域很小,只有1M,特点是存取速度很快,所以在stack中存放的都是快速执行的任务,基本数据类型的数据,和对象的引用(reference),方法的拷贝运行。只有处于栈顶的方法才处于运行状态,其他的属于就绪状态。

本地方法栈:栈中方法拷贝运行时,因为底层时c语言的方法,所以需要本地方法栈,来翻译方法,使之成为操作系统本身的内核方法,对接驱动。

每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器。PC寄存器里保存有当前正在执行的JVM指令的地址

小例子:

w,e的指向确实改变了,但是没有影响到x1,x2。

什么是Class常量池?

  • 我们写的每一个Java类被编译后,就会形成一份Class文件Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用

  • 每一个Class文件中都有一个Class常量池

被编译后的类就会进入Class常量池

IO操作

IO操作,就是将数据写入内存或从内存输出的过程,也指应用程序和外部设备之间的数据传递。

常见IO流操作,一般指内存与磁盘间的输入输出流操作。

final关键字

1.对象构造函数内有final域,必须先用构造函数构造对象,再把对象赋给其他引用 2.如果对象有final域,必须先读对象的引用,再读final域。

这两个规则的目的是保证:在对象引用为任意线程可见之前,对象的final域已经被正确初始化过了,而普通域就不具有这个保障。

请看下面的Java代码,它定义了一个类Person,有两个域:name和age。name是一个final域,age是一个非final域。然后,它创建了一个Person对象,并在另一个线程中读取它的域。

c
lass Person {
    final String name; // final域
    int age; // 非final域
public Person(String name, int age) {
    this.name = name; // 写final域
    this.age = age; // 写非final域
}
}
​
public class Test {
    static Person person;
    public static void main(String[] args) throws InterruptedException {
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            person = new Person("Alice", 20); // 把对象引用赋值给person
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            if (person != null) { // 读对象引用
                System.out.println(person.name); // 读final域
                System.out.println(person.age); // 读非final域
            }
        }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
}
}

根据final的重排序规则,线程t2在读取person.name时,一定能看到正确的值Alice,因为写final域和赋值对象引用之间不能重排序。但是,线程t2在读取person.age时,可能看到的不是正确的值20,而是0,因为写非final域和赋值对象引用之间可以重排序。这就是final和非final域的区别

使用多线程可能会带来的问题

并发编程的目的就是为了能提高程序的执行效率提高程序运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、死锁、线程不安全等等。

如何理解线程安全不安全?

线程安全和不安全是在多线程环境下对于同一份数据的访问是否能够保证其正确性和一致性的描述。

  • 线程安全指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性。

  • 线程不安全则表示在多线程环境下,对于同一份数据,多个线程同时访问时可能会导致数据混乱、错误或者丢失。

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

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

相关文章

牛客_左右最值最大差_C++题解

原题链接:牛客 题目缩写:给你一个数组,由你来进行一个切分,分为两份,每份至少有1个元素;你分出来的这两个区间中各自有一个最大值,两者之差再求绝对值就是答案,这个答案越大越好&am…

认识异常(2)

❤️❤️前言~🥳🎉🎉🎉 hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥&a…

【Linux系统】操作备忘录

Linux命令 打开终端的快捷键:Ctrl Alt t 退出终端的命令:exit 终端命令行复制/粘贴的快捷键 :Ctrl Shift c / v 对于所有不太熟悉的命令,都可以在终端输入 命令名称 --help 来查看具体用法。例如: 文件和目录…

电池电量监测系统设计 单片机+LabVIEW+Matlab+Protues+Keil程序

目录 前言 提供 软件 系统展示 1.放电试验及其处理 2.硬件系统原理图 3.下位机程序 4.显示 5.上位机界面 6.上位机程序 7.文档 资料下载地址:电池电量监测系统设计 单片机LabVIEWMatlabProtuesKeil程序 前言 这套系统首先使用Matlab分析获得了电压…

项目5-博客系统3+接口完

1.实现显示用户信息 ⽬前⻚⾯的⽤⼾信息部分是写死的. 形如 我们期望这个信息可以随着用户登陆而发生改变. • 如果当前⻚⾯是博客列表⻚, 则显⽰当前登陆⽤⼾的信息. • 如果当前⻚⾯是博客详情⻚, 则显⽰该博客的作者⽤⼾信息. 注意: 当前我们只是实现了显⽰⽤⼾名, 没有…

Swagger的使用教程

Swagger简介 Swagger是一个规范和完整的API框架,可用于生成、描述、调用Restful风格的Web服务的接口文档。如果你在SpringBoot中使用的话,在项目启动后可以自动生成在线可调用的API文档,非常方便! 在SpringBoot中集成 首先在po…

797. 所有可能的路径

给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序) graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向…

办公小助手来啦! Textin接口,轻松提取文件信息,让你如虎添翼!

😎大家是不是经常为了一堆文件而头疼呢?📚别担心,Textin接口它来了!🎉 一、Textin的神秘面纱 1. Textin是谁? 🔍Textin接口,一款专业的文件信息提取工具,只…

Arco design 发布到生成环境F5刷新报错404

问题:开发环境没问题,生成环境正常跳转也没问题但是F5刷新报错 解决办法一:修改 history: createWebHistory(), 改为history: createWebHashHistory(),

微服务-6 Gateway网关

一、网关搭建 此时浏览器访问 localhost:10010/user/list 后正常返回数据,说明网关已生效,其原理流程图如下: 二、网关过滤器 作用:处理一切进入网关的请求和微服务响应。 1. 网关过滤器的分类: a. 某个路由的过滤器 …

C语言 | Leetcode C语言题解之第26题删除有序数组中的重复项

题目&#xff1a; 题解&#xff1a; int removeDuplicates(int* nums, int numsSize) {if (numsSize 0) {return 0;}int fast 1, slow 1;while (fast < numsSize) {if (nums[fast] ! nums[fast - 1]) {nums[slow] nums[fast];slow;}fast;}return slow; }

教程备忘 一文搞定 cmake 全部技巧之 app 和 lib 的 cmake 系统

1&#xff0c;APP cmake 1.1 hello_app_01 文件&#xff1a;hello.cpp add_impl.cpp sub_impl.cpp CMakeLists.txt hello.cpp #include <iostream> float add(float, float); float sub(float, float);int main() {float a, b;a 7.7f;b 2.333f;std::cout<&l…

Java面试之redis篇

文章目录 布隆过滤器BloomFilter布隆过滤器是什么、能干嘛原理hash冲突导致数据不精确 缓存预热缓存雪崩发生预防 缓存穿透缓存穿透是什么解决 工作中哪里使用过redis 布隆过滤器BloomFilter 布隆过滤器是什么、能干嘛 由一个初值都为零的bit数组和多个哈希函数构成&#xff…

系统架构设计图

首先明确应用架构的定义&#xff0c;从百度百科上即可了解到何为应用架构&#xff1a; 应用架构&#xff08;Application Architecture&#xff09;是描述了IT系统功能和技术实现的内容。应用架构分为以下两个不同的层次&#xff1a; 企业级的应用架构&#xff1a;企业层面的应…

SpringBoot3整合Mybatis plus

Java版本&#xff1a;17 Spring Boot版本&#xff1a;3.1.10 Mybatis plus版本&#xff1a;3.5.5 源码地址&#xff1a;Gitee仓库 01 创建我们的项目工程 首先&#xff0c;我们创建一个maven工程spring-boot3-demo&#xff0c;pom文件配置如下。 这里我们将spring-boot-start…

生成对抗网络(GAN)工作原理及应用

文章目录 1、概述2、GAN的工作原理2.1、生成器&#xff08;Generator&#xff09;2.2、判别器&#xff08;Discriminator&#xff09; 4、GAN的优点5、GAN的应用6、注意事项7、总结 1、概述 生成对抗网络&#xff08;Generative Adversarial Network&#xff0c;简称GAN&#…

JAVA实现人工智能,采用框架SpringAI

Spring AI介绍 Spring AI是AI工程师的一个应用框架&#xff0c;它提供了一个友好的API和开发AI应用的抽象&#xff0c;旨在简化AI应用的开发工序&#xff0c;例如开发一款基于ChatGPT的对话应用程序。 项目地址&#xff1a;https://github.com/spring-projects-experimental/sp…

C#泛型,利用反射创建和普通创建泛型

泛型,利用反射创建和普通创建 反射 var input Activator.CreateInstance(typeof(Input<>).MakeGenericType(typeof(T))) as dynamic;typeof(T)这个位置可以塞入不同的类型 Activator.CreateInstance 反射动态创建实例&#xff1a; 这种方式使用 Activator.CreateIns…

【1000个GDB技巧之】如何在远端服务器打开通过vscode动态观测Linux内核实战篇?

Step: 配置ssh的服务端host &#xff08;也可以直接在vscode中配置&#xff0c;忽略&#xff09; 主要步骤&#xff1a;在~/.ssh/config中添加服务端的host&#xff0c;以便vscode的remote中能够登录 详细配置过程参考兄弟篇文章&#xff1a;ssh config如何配置用host名替代ro…