工作内存与主内存
java内存模型并不真正的存在,是一种规则规定了程序中各个变量的访问方式。线程运行的时候,每个线程创建时候jvm都会为其创建一个工作内存,java的所有的变量都存放在主内存中是共享的数据区域。线程对变量进行操作,要将变量从主内存拷贝到自己的工作内存中,线程的工作内存中存放了内存副本,操作完成之后在将变量写回到主内存中。线程之间的的传递必须要通过主内存。主内存是线程共享的包括堆和方法区,工作内存是线程私有的包括栈,程序计数器,本地方法栈
zejian博主阐述的:
“实例对象的成员变量,不管它是基本数据类型或者包装类型(Integer、Double等)还是引用类型,都会被存储到堆区”
这句话可以这样理解,如果创建了一个实例,那么该实例中包含了该类的所有的成员变量,这些成员变量叫做实例对象的成员变量,这些成员变量随对象存放在堆中。
cpu 寄存器 cpu缓存 主内存组成的硬件存储架构
计算机中有cpu 寄存器 cpu缓存 主内存,当cup需要数据的时候,会先读取一部分数据到cpu缓存中,如果获取数据的时候,首先会从cpu缓存中获取读到寄存器中,如果cpu缓存没有,则直接从内存中获取读到寄存器中,写入数据的时候,先将寄存器中的数据刷新到cpu缓存中,之后再刷新到内存中。cpu能在cpu缓存中读取数据加载到缓存中,就是缓存命中率。寄存器是cpu是直接访问和处理数据的临时数据存储空间。
java线程的实现原理:
在window和linux中,java线程是基于一对一模型实现的,使用线程的时候在java虚拟机内部是调用当前操作系统的内核线程来完成当前任务的。每个线程映射一个内核线程,通过线程能够调用内核线程,再由操作系统内核将任务映射到各个处理器上。
内核线程是由操作系统内核支持的线程由操作系统内核完成线程的切换,内核操作调度器对线程执行调度,并将线程映射到各个处理器上,每个内核线程都可以一视为内核的一个分身,是操作系统可以处理多个任务的原因
通过这张图可以知道,线程可以并发操作的原因
真正并发操作的原因是线程映射到操作系统的内核线程,然后内核操作调度器对内核线程进行调度并映射到多处理器上。通常我们所说的并发指的是时间片轮转法的假象的并发
工作内存主内存与cpu 寄存器 cpu缓存 主内存的硬件存储架构的关系
线程映射到操作系统层面上就是内核线程,与线程相关的工作内存主内存映射到硬件存储层面上可以是主内存可以是cpu缓存可以是寄存器是交叉的关系,没有固定的内容
线程安全问题:就是存在共享资源,多个线程对共享资源进行操作。线程将变量从主内存中拷贝到工作内存中,对变量的副本进行修改,同时另一个线程拷贝了变量的副本进行了修改,这个时候,操作完成后向主内存中刷新数据这时候就出现问题,引起线程的一致性问题,可见性问题