• jvm内存模型


    https://www.cnblogs.com/liclBlog/p/9379767.html

    补充:

    可见性

     个线程修改了变量,其他线程可以立即知道

    保证可见性的方法

    - volatile

    - synchronized (unlock之前,写变量值回主存)

    - final(一旦初始化完成,其他线程就可见)

    有序性

    在本线程内,操作都是有序的

    在线程外观察,操作都是无序的。(指令重排 或 主内存同步延时)

    指令重排

    – 线程内串行语义

                  •写后读  a = 1;b = a;  写一个变量之后,再读这个位置。

                  •写后写  a = 1;a = 2;  写一个变量之后,再写这个变量。

                  •读后写  a = b;b = 1;  读一个变量之后,再写这个变量

                  •以上语句不可重排

                  •编译器不考虑多线程间的语义

    可重排: a=1;b=2;

    指令重排会破坏程序间的有序性

    class OrderExample {
    int a = 0;
    boolean flag = false;
    
    public void writer() {
        a = 1;                   
        flag = true;           
    }
    
    public void reader() {
        if (flag) {                
            int i =  a +1;      
            ……
        }
    }
    }
    

    线程A首先执行writer()方法,线程B线程接着执行reader()方法 ,线程Bint i=a+1 是不一定能看到a已经被赋值为1

    因为在writer中,两句话顺序可能打乱。

    线程A可能是

    flag=true

    a=1

    线程B可能是

    flag=true(此时a=0)

    防止指令重排的方法是保证线程的安全

    指令重排的基本原则

    – 程序顺序原则:一个线程内保证语义的串行性

    – volatile规则:volatile变量的写,先发生于读

    – 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前

    – 传递性:A先于B,B先于C 那么A必然先于C

    – 线程的start方法先于它的每一个动作

    – 线程的所有操作先于线程的终结(Thread.join())

    – 线程的中断(interrupt())先于被中断线程的代码

    – 对象的构造函数执行结束先于finalize()方法

    解释运行

    – 解释执行以解释方式运行字节码

    – 释执行的意思是:读一句执行一句

    编译运行(JIT

    – 将字节码编译成机器码

    – 接执行机器码

    – 行时编译

    编译后的性能有数量级的提升。

  • 相关阅读:
    echarts在ie浏览器y轴坐标偏移向上
    git常用命令总结[转]
    char和varchar类型的区别
    关于猴子选大王的问题
    VIM折叠代码命令
    用excel打开文本内容
    php事务操作示例
    Iframe内嵌Cookie丢失问题
    VIM折叠代码命令
    git常用命令总结[转]
  • 原文地址:https://www.cnblogs.com/liclBlog/p/15349558.html
Copyright © 2020-2023  润新知