java线程学习(五)—java内存模型自己总结

来源:互联网 发布:淘宝 订单 清洗 编辑:程序博客网 时间:2024/04/29 17:58

Java内存模型

 

1      Java内存模型的概念

内存模型的概念:在特写的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。

Java内存模型的概念:java虚拟机规范中定义的一种内存模型。

2      Java内存模型的作用

1)        屏蔽各种硬件和操作系统之间的差异,使java程序在各平台下能达到一致的内存访问效果。

2)        在各处理器架构中为并发提供一致语议的内存模型。

3      Java内存模型的实现方法

3.1    Java内存模型的目标:

定义程序中各个变量的访问规则。即虚拟机中将变量储存到内存和从内存中取出变量这样的底层细节。

此处的变量:实例变量、静态变量、构成数组对象的元素。并不包括局部变量和方法参数,后者是线程私有的,不存在竞争问题。

 

3.2    主内存与工作内存

 

3.2.1    主内存

1)        概念

Java内存模型规定了所有变量都存储在主内存中。主内存仅是虚拟机内存的一部分。

2)        作用

             线程间变量值的传递都需要通过主内存来完成。

3)        实现方式

主内存主要对应于java堆中对象实例的数据部分。从更低层次上来说,主内存直接对应着物理硬件的内存。

 

3.2.2    工作内存

1)        概念

 

               保存该线程所使用的变量的主内存副本拷贝(部分拷贝,不是全部拷贝)。

2)        作用

                线程对变量的所有操作(读取、赋值等)都必须在工作内存中执行,不能直接读写主内存中的变量。线程中变量的值的传递均需要通过主内存来完成。

 

3)        实现方式

对应虚拟机栈的部分区域。为了获得更快的运行速度,虚拟机可能会让工作内存优先存储于寄存器和高速缓存中。因为程序运行时主要访问读写的是工作内存。

 

3.3    内存间交互操作

1)        概念

一个变量如何从主内存拷贝到工作内存,又如何从工作内存同步回主内存的实现细节。

2)        作用

8种内存访问规则操作以及相应的规则限定,以及对volatile的一些特殊规定,就可以确定java中哪些内存访问操作在并发下是线程安全的。

3)        实现方式

8种操作及操作的顺序。

3.4    volatile变量的特殊规则

Jvm提供的最轻量级的同步机制。

Volatile变量的两种特性:

1)        保证此变量对所有线程的可见性

2)        禁止指令重排序优化

3.5    Long型和double型变量

无须过多考虑,一般虚拟机都会把这种变量做为原子操作。

 

3.6    原子性、可见性和有序性

Java内存模型是围绕着原子性,可见性和有序性来建立的。

 

1)        原子性

a)        存取内存变量的原子操作,如read,load等。

b)        对基本变量的访问读写是具备原子性的。

c)        Synchronized同步块之间的操作。

 

2)        可见性

a)        概念:

当一个线程修改了共享变量的值,其它线程能够立即得知这个修改。

b)        实现方式:

java内存模型是通过主内存作为传递媒介,通过在变量修改后将新值同步到主内存,在变量读取前从主内存刷新变量值。

1. Volatile变量:可以保证新值能立即同步到主内存,以及每次使用前能立即从主内存中刷新。

2.synchronized:同步块的可见性是由“对一个变量执行unlock之前,必须把变量同步回主内存中”。

3.final变量:被final修饰的变量在构造器中一旦初始化完成,并且没有在构造器中把this引用传递出去,那么其它线程就能看到此final字段的值。

3)        有序性

Voliatle:f禁止指令重排序。

Synchronized:一个变量在同一时刻只允许一条线程对其进行Lock操作。

 

3.7    先行发生原则

          Java 语言中定义了先行发生原则。如果仅仅依靠volatile和synchronized来保证有序,操作会非常麻烦。

 

4      Java与线程

4.1    线程的概念

线程是比进程更轻量的调度执行单位,是CPU的执行单位。

4.2    线程的作用

可以把进程的资源分配和执行调度分离开,各个线程即可以共享进程资源(内存地址,文件I/O),又可以独立调度。

 

4.3    线程的实现

各种操作系统都提供了线程的实现。JAVA在不同硬件和操作系统平台下对线程进行了统一处理。每个已执行start()且还未结束的java.lang.Thread类的实例就代表了一个线程。

实现线程的三种方式:内核线程实现、用户线程实现和用户线程加轻量级进程混合实现。

4.4    JAVA线程调度

      线程调度是指系统为线程分配处理器使用权的过程。主要调度分两种:协同式调度和抢占式调度。

     协同式调度:线程的执行时间由线程自己来控制,线程把自己的工作执行完了之后,主动通知系统切换到另外一个线程上。

     抢占式调度:由操作系统来为线程分配执行时间。

 

     线程的优先级:两个线程同时处于Ready时,优先级越高的线程越容易被系统选择执行。但线程优先级不是太靠谱。JAVA线程是映射到操作系统原先线程来实现的,最终的线程调度还是取决于操作系统。优先级也可能被系统自行改变。

 

0 0