首页 > 系统相关 >Java 线程内存模型

Java 线程内存模型

时间:2023-01-15 10:31:29浏览次数:55  
标签:Java 私有 模型 int 线程 内存


1. 前言

本节内容是从操作系统的层面谈并发,本节课程我们需要掌握如下内容:

  • 了解 Java 的内存模型定义,是 Java 并发编程基本原理的基础知识;
  • 从概念上了解线程的私有内存空间和主内存,能够从全局上了解线程是如何进行内存数据的存取操作的;
  • 了解线程拥有私有空间的意义,私有空间能够为线程提供独有的数据,其他线程不可干扰;
  • 在多线程环境下,主内存操作共享变量需要注意的事项需谨记,数据安全问题很重要;
  • Java 线程也是拥有生命周期的,了解它的生命周期,从宏观上了解线程。

2. 什么是 Java 的内存模型

定义: Java 内存模型(即 Java Memory Model,简称 JMM)本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。

3. Java 线程的私有内存和主内存

工作内存(私有):由于JVM 运行程序的实体是线程,而每个线程创建时 JVM 都会为其创建一个工作内存(栈空间),用于存储线程私有的数据。线程私有的数据只能供自己使用,其他线程不能够访问到当前线程私有的内存空间,保证了不同的线程在处理自己的数据时,不受其他线程的影响。

主内存(共享):Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问。从上图中可以看到,Java 的并发内存模型与操作系统的 CPU 运行方式极其相似,这就是 Java 的并发编程模型。通过创建多条线程,并发的进行操作,充分利用系统资源,达到高效的并发运算。

4. 线程拥有私有空间的意义

我们知道,线程的私有空间中存储的数据,仅供当前线程自己使用,其他线程不能够对数据进行访问。线程的私有空间会存放很多程序运行时所必须的数据,如:

程序计数器:记录当前方法执行到了哪里,以便 CPU 切换回来之后能够继续执行上次执行到的位置,而不会进行重复执行或者遗漏。

局部变量:局部变量是方法中的变量,只供当前方法使用。

方法参数:Java 方法会定义自己的入参,入参的真实值也会记录到内存空间供当前线程使用。

由于线程的内存空间会存放很多数据,这里只提以上三中数据以供同学理解线程私有空间的意义。
为了加深理解,我们一起看一个简单的代码示例并进行分析:

public class DemoTest{
public static void main(String[] args) {
sum(10); // 解析点 3
}
public static void sum(int num) {
int i = 5; // 解析点 1
set(); //解析点 2
System.out.println("num+i = "+ (num + i));
}
public static void set() {
int i = 100;
}
}

在给出结果之前,我们来分析下:
解析点 1 :设置 i 的值为 5;
解析点 2: 调用 set() 方法,逻辑如下。

public static void  set() {
int i = 100;
}

那最终的结果是多少呢?
解析点 3:我们传入的 sum 的参数值是 10,如果想确定结果,只要确定另外一个加数 i 的值就行了。我们通过分析,在方法 sum(int num) 中的 int i = 5 与方法 set() 中的 int i = 100 是两个不同的方法的局部变量,属于线程私有的。互相不会影响,所以set() 方法中的 int i = 100 不会影响最终的结果:

num+i = 15

5. 主内存操作共享变量需要注意的事项

  • 确定是否是多线程环境:多线程环境下操作共享变量需要考虑线程的安全性;
  • 确定是否有增删改操作:多线程环境下,如果对共享数据有增加,删除或者修改的操作,需要谨慎。为了保证线程的同步性,必须对该共享数据进行加锁操作,保证多线程环境下,所有的线程能够获取到正确的数据。如生产者与消费者模型,售票模型。这些会在后续章节进行代码实战演练;
  • 多线程下的读操作:如果是只读操作,对共享数据不需要进行锁操作,因为数据本身未发生增删改操作,不会影响获取数据的准确性。

6. Java 线程的生命周期

每个事物都有其生命周期,也就是事物从出生开始到最终消亡这中间的整个过程。在其整个生命周期的历程中,会有不同阶段,每个阶段对应着一种状态,比如:人的一生会经历从婴幼儿、青少年、青壮年、中老年到最终死亡,离开这人世间,这是人一生的状态。

同样的,线程作为一种事物,也有生命周期,在其生命周期中也存在着不同的状态,不同的状态之间还会有互相转换。

Java 线程的声明周期会经历 6 中不同的状态变化,后续章节会有详细描述。从线程的创建到线程执行任务的完成,即 Java 线程的生命周期。

7. 小结

Java 并发理论基础是基于Java 的内存模型的,了解 Java 内存模型,能够更有助于后续对并发知识的理解和运用了。Java 的内存模型是并发原理的基础,在了解内存模型的基础上去理解共享内存和私有内存,了解不同内存状态以及 Java 线程的生命周期至关重要。

标签:Java,私有,模型,int,线程,内存
From: https://blog.51cto.com/10zhancom/6008331

相关文章

  • Java Keytool 介绍
    keytool是Java自带的一个安全相关的工具,用于管理密钥和证书;本文主要介绍其基本使用;文中所使用到的软件版本:Java1.8.0_321。1、简介keytool命令是一个密钥和证书管理......
  • java:Cassandra入门与实战——上
    一、数据存储方式和NoSQL1.1数据存储方式互联网时代各种数据存储方式层出不穷,有传统的关系性数据库如:MySQL、Oracle等,;有全文检索框架如:ElasticSearch、Solr;有NoSQL如:Cassan......
  • Java学习:ribbon的常用负载均衡算法分析
    1.Ribbon介绍因为微服务是目前互联网公司比较流行的架构,所以spring就提供了一个顶级框架-springcloud,来解决我们在开发微服务架构中遇到的各种各样的问题,今天的主角是sprin......
  • Java教程学习:揭秘什么是面向接口编程
    先用一个案例来给大家说明一下面向接口编程。案例:有一个电脑类(Computer),电脑除了有基本的开机关机功能外,还有连接任何外接设备的功能,比如能电脑能连接外置键盘(Keyboard),鼠标......
  • java基础教程:IO流
    一:IO流的分类1)按流向分:输入流:读取数据,把持久设备的数据读取到内存中。输出流:写出数据,把内存的数据写出到持久设备。2)按数据类型分:计算机中一切数据都是:字节数据。字符数据:底......
  • Java基础教程:ArrayList入门
    1ArrayList类概述什么是集合提供一种存储空间可变的存储模型,存储的数据容量可以发生改变ArrayList集合的特点底层是数组实现的,长度可以变化泛型的使用用于约束集合中存储......
  • java:Redis持久化
    一.redis持久化的介绍Redis的持久化指的是将内存中redis数据库运行的数据,写到硬盘文件上。Redis持久化的意义主要在于故障恢复,比如你部署一个Redis,作为缓存有可能里边有......
  • JavaScript 中搜索数组元素的四种方法
    在实际开发当中,我们经常会遇到类似诸如下面的需求:获取满足特定条件的数组中的所有项目要检查是否满足条件?检查数组中是否有特定值?在数组中找到指定值的索引?在本文中,我们将讨......
  • 《跟老卫学 HarmonyOS 开发》:DevEco Studio 启用Java预览器
    老版的DevEcoStudio只支持layout资源类型的XML文件的预览。在新版的DevEcoStudio已经能够支持 Ability/AbilitySlice的Java类文件的预览。新版的DevEcoStudio默认......
  • 【Java 数据结构及算法实战】系列 013:Java队列07——双端队列Deque
    双端队列(Deque),顾名思义是可以在队列的两端插入和移除元素的特殊队列。Java提供了java.util.Deque<E>接口以提供对双端队列的支持。该接口是JavaCollectionsFramework的一......