JVM内存模型详解

JVM运行时数据区

JVM运行时数据区
详见Java程序运行原理分析:https://blog.csdn.net/maxleader/article/details/104098513

从内存结构到内存模型

内存结构 - 内存模型

多线程中的问题

  • 所见非所得;
  • 肉眼无法检测程序准确性;
  • 不同的运行平台有不同的表现;
  • 错误很难重现;

工作内存缓存

工作内存缓存

指令重排序

指令重排序

Java内存模型含义

内存模型含义

Shared Variables共享变量描述

共享变量描述

线程操作的定义

线程操作定义
程序顺序:如果一个程序没有数据竞争,那么程序所有执行看起来顺序都一致;
本规范只涉及线程间的操作;

对于同步的规则定义

同步规则定义

Happens-before先行发生原则

先行发生原则

volatile关键字

volatile关键字

使用volatile代码示例

import java.util.concurrent.TimeUnit;

// 1、 jre/bin/server  放置hsdis动态链接库
//  测试代码 将运行模式设置为-server, 变成死循环   。 没加默认就是client模式,就是正常(可见性问题)
// 2、 通过设置JVM的参数,打印出jit编译的内容 (这里说的编译非class文件),通过可视化工具jitwatch进行查看
// -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation -XX:LogFile=jit.log
//  关闭jit优化-Djava.compiler=NONE
public class VisibilityDemo1 {
	// 状态标识 (不用缓存)
    private volatile boolean flag = true;
    
    // 源码 -> 字节码class
    // JVM 转化为 操作系统能够执行的代码 (JIT Just In Time Compiler 编译器 )(JVM  --  client , --server)
    public static void main(String[] args) throws InterruptedException {
        VisibilityDemo1 demo1 = new VisibilityDemo1();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                // class ->  运行时jit编译  -> 汇编指令 -> 重排序
                while (demo1.flag) { // 指令重排序
                    i++;
                }
                System.out.println(i);
            }
        }).start();

        TimeUnit.SECONDS.sleep(2);
        // 设置is为false,使上面的线程结束while循环
        demo1.flag = false;
        System.out.println("被置为false了.");
    }
}

使用synchronized代码示例

import java.util.concurrent.TimeUnit;

public class VisibilityDemo2 {
    // 状态标识
    private static boolean is = true;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while (VisibilityDemo1.is) {
                    synchronized (this) {
                        i++;
                    }
                }
                System.out.println(i);
            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 设置is为false,使上面的线程结束while循环
        VisibilityDemo2.is = false;
        System.out.println("被置为false了.");
    }
}

final在JVM中的处理

final在JVM中的处理

final代码示例

public class FinalDemo {
    public static final String a = "hello tony";
    public static void main(String[] args) {
    }
}

// 官方示例,可能会读取到y的值为0
class FinalFieldExample {
    final int x;
    int y;
    static FinalFieldExample f;

    public FinalFieldExample() {
        x = 3;
        y = 4;
    }

    static void writer() {
        f = new FinalFieldExample();
    }

    static void reader() {
        if (f != null) {
            int i = f.x;  // guaranteed to see 3 肯定是3
            int j = f.y;  // could see 0 可能看到0
        }
    }
}

// 官方示例,new A().f() 可能返回 -1, 0, or 1.
class A {
    final int x;

    A() {
        x = 1;
    }

    int f() {
        return d(this, this);
    }

    int d(A a1, A a2) {
        int i = a1.x;
        g(a1);
        int j = a2.x;
        return j - i;
    }

    static void g(A a) {
        // uses reflection to change a.x to 2
        // 使用反射技术修改A.x为2
    }
}

Word tearing字节处理

Word tearing字节处理

Word tearing代码示例

// https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4
// 官方提供的示例,检查有没有WordTearing情况
public class WordTearingDemo extends Thread {
    static final int LENGTH = 8;
    static final int ITERS = 1000000;
    static byte[] counts = new byte[LENGTH];
    static Thread[] threads = new Thread[LENGTH];

    final int id;

    WordTearingDemo(int i) {
        id = i;
    }

    @Override
    public void run() {
        byte v = 0;
        for (int i = 0; i < ITERS; i++) {
            byte v2 = counts[id];
            if (v != v2) {
                System.err.println("Word-Tearing found: " +
                        "counts[" + id + "] = " + v2 +
                        ", should be " + v);
                return;
            }
            v++;
            counts[id] = v;
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < LENGTH; ++i)
            (threads[i] = new WordTearingDemo(i)).start();
    }
}

double和long的特殊处理

double和long的特殊处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值