原创 【一起学习JVM】Java内存模型与线程

发布时间:2021-06-24 15:57:32 浏览 27 来源:猿笔记 作者:唐宋xy

    Java内存模型(JMM)的定义是为了屏蔽硬件和操作系统的内存的访问差异,通过定义主内存和工作内存来定义各个变量的访问规则。工作内存中的变量需要从主内存中读取变量:写变量的时候只能在工作内存中完成:不同的线程的工作内存之间是隔离的,线程之间的变量传递需要通过主内存完成,当工作线程中的变量更新之后,将其他线程的工作内存中的变量失效,然后当使用该变量时重新从主内存中读取变量,Java内存中所有的有序性并不是都依赖volatile和sychronized来保证的,Thread对象的`start`操作优先于对此线程的每一个操作。


    #主题列表:juejin,github,smartblue,cyanosis,channing-cyan,fancy,hydrogen,condensed-night-purple,greenwillow,v-green,vue-pro,healer-readable,mk-cute,jzman,geek-black,awesome-green,qklhk-chocolate

    #投稿主题:

    theme:smartblue

    highlight:

    ##Java内存模型与线程

    ###Java内存模型

    Java Memory Model (JMM)的定义是屏蔽硬件和操作系统的内存访问差异,通过定义主内存和工作内存来定义各个变量的访问规则。

    ![Java内存模型](

    -所有变量都存储在主内存中,工作内存是每个线程自己的私有内存。工作存储器中的变量需要从主存储器中读取。写变量的时候只能在工作内存中完成,不能直接写到主存。不同线程的工作内存是隔离的,线程间的变量传递需要通过主存完成。

    #####Volatile变量的访问规则

    Java内存模型的三个特征:*可见性、原子性和顺序* *

    -Volatile可以保证的特性是:可见性和有序性

    -可见性:工作线程中的变量更新后,会立即写回主存,当前主存中的变量会被锁定。更新完成后,其他线程的工作内存中的变量会失效,然后在使用变量的时候再从主存中读取变量,也就是读取最新的值。

    -订单:订单由内存屏障保证

    Volatile不能保证原子性。如果你需要保证多个操作的原子性,那么抛出需要通过锁定来保证原子性

    -volatile在同步方面比其他同步机制更快,并且增加了并发性。因为volatile在读取操作上和普通变量基本相同,所以写入操作相对较慢。因为需要插入多个内存屏障来保证顺序,相对于其他同步机制来说速度相对较快,所以volatile也称为轻量级同步机制。

    #####hapens-before规则

    Java内存中的所有有序性不是通过volatile和sychronized来保证的,而是通过定义“发生在前”的规则,主要保证两个操作之间的执行顺序关系和程序执行的正确性

    -* *程序令规则* *

    在单线程中,按照程序的代码顺序执行,前面写的操作在后面的操作中最先发生

    -* *管道侧锁定规则* *

    解锁操作首先发生在同一把锁上的锁定操作之后

    -**volatile变量规则**

    对易失性变量的写操作首先发生在对该变量的读操作之后

    也就是前面有一行代码写volatile变量,后面有一行代码读同样的volatile变量,所以写操作优先于读操作,不会乱序。

    -* *线程启动规则* *

    线程对象的“开始”操作优先于该线程上的每个操作

    -* *线程终止规则* *

    线程中的所有操作都发生在该线程的终止操作之前

    -* *线程中断规则* *

    对线程的“中断()”方法的调用首先发生在被中断线程的中断事件检测中

    -* *对象终止规则* *

    对象的初始化(调用构造函数)首先发生在对象的“finalize()”方法中

    -* *传递性* *

    如果操作A发生在操作B之前,操作B发生在操作C之前,那么操作A也必须发生在操作C之前。

    ###Java线程

    # # # # #如何实现线程

    线程比进程轻,可以实现独立的CPU调度,提高多核CPU的优势。那么如何在Java中实现线程呢?从Java中的‘thread’类可以看出,大多数操作线程的方法,比如start方法,都是本机的。Java线程只封装操作系统的线程,屏蔽了不同平台下线程操作的差异。

    实现线程有三种主要方式:使用内核线程、使用用户线程、使用用户线程和轻量级进程

    #####Java线程调度

    线程调度是系统为不同线程分配不同CPU使用时间的过程。Java中主要有两种线程调度方法:* *抢占式线程调度* *,* *协作式线程调度* *,Java中使用的调度方法是抢占式线程调度

    -* *抢占式线程调度* *:每个线程的执行时间由系统分配,线程的切换也由系统分配,但是每个线程的执行时间分配可以通过* *优先级* *来调整

    -* *协同线程调度* *:线程的执行由线程本身控制,每个线程在执行完成后由其他线程执行。

    # # # # #线程状态

    一个线程有五种状态,一个线程只能同时处于其中一种状态。

    这五种线程状态通过特定的触发模式从一种状态变为另一种状态。

    -* *新建* *:当线程已创建但未启动时,状态为新建

    -* *运行* *:线程调用` start `方法时,处于运行状态。

作者信息

唐宋xy [等级:3]
发布了 15 篇专栏 · 获得点赞 9 · 获得阅读 794

相关推荐 更多