Java中内存模型的原理是什么

Java中内存模型的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

1。JMM简要知识

语义规范

    <李>

    Java编程语言的语义允许编译器和微处理器执行优化,从而与不正确同步的代码进行交互来完成工作。

    <李>

    线程内语义是单线程程序的语义,它允许根据线程内读操作看到的值来完全预测线程的行为,由于单线程内的实现是在其上下文执行的,可以通过评估线程的实现从而确定执行中的线程的操作是否合法。李李

    <>

    程序遵循线程内语义:在线程隔离状态下,每个线程的操作必须由该线程的语义控制,但是每个读操作看到的值由内存模型决定。

JMM规范

    <李>

    从数据存储上,对于共享数据的读写操作,JMM会通过线程工作内存以及JVM的堆内存来对数据进行读写操作(类比互联网业务,工作内存类比为复述,等缓存,堆内存类比为数据储存载体,如数据库)

    <李>

    从代码优化上,JMM为了提升性能,会针对程序顺序代码进行重排序甚至删除不必要的同步代码

JMM概要

    <李>

    给定程序以及一个检测程序是否合法的执行跟踪,JMM工作原理是检查执行跟踪中的每个读,并根据某些规则检查读观察到的写是否有效

    <李>

    主要保证执行的每个结果与内存模型预期值一致,那么它可以不关心实现者是如何实现程序的行为

    <李>

    内存模型决定在程序的每个点可以读取哪些值。在隔离状态下,每个线程的操作必须由该线程的语义控制,但是每个读操作看到的值由内存模型决定

    <李>

    每次在线程内对变量进行写行为产生一个线程间的动作时,它必须匹配程序顺序中紧随其后的读行为的线程间动作,其中对于线程的读操作行为获取的值是由于JMM决定的值

2。JMM与顺序一致性模型

程序顺序与顺序一致性

    <李>

    程序顺序

    <李>

    可描述为线程间所有动作是根据线程内语义执行操作顺序的一个集合

    <李>

    简言之,就是在线程内的操作所见即所得,即程序代码顺序

<李>

顺序一致性内存模型

<李>

一个线程所有操作都必须按照程序的顺序来执行

<李>

不论线程是否同步,所有线程都只能看到一个单一的操作执行顺序,并且每个操作都必须是原子性操作并立即对其他所有线程可见

<李>

顺序一致性问题

<李>

如果内存模型使用一致性模型,则将会导致编译器和处理器的优化策略变得不合法

JMM在顺序一致性方面的努力

    <李>

    源代码

 <代码>//共享。java 
int pwrite=0;
int cwrite=0;
//制片人。java
=0; int个帖子:
int r1=0;
run () {
,,r1=20;//- - - - - - 1=cwrite;
个帖子://- - - - - - 2
pwrite=10;//- - - - - - 3
}
//消费者。java
int cread=0;
int r2=0;
run () {
cread=pwrite;//- - - - - - 4
r2=21;//- - - - - - 5
cwrite=20;//- - - - - - 6
}
    <李>

    代码分析

    <李>

    基于JMM模型:由于存在数据竞争,上面的代码执行顺序会在编译器阶段,JMM允许对程序代码进行重排序,输出结果会出现<强>帖子:=cwrite=20与cread=pwrite=10 强的情况

    <李>

    基于一致性内存模型:将会正常输出,不会出现<强>帖子:=cwrite=20与cread=pwrite=10 强的情况,但是线程之间的顺序会交替执行

<李>

加锁方案

<李>

基于JMM模型:保证输出结果的正常,但是在上述线程内执行的顺序会被重排序

<李>

一致性内存模型:不会打乱顺序,仍然正常结果输出

<李>

小结

Java中内存模型的原理是什么