java高级-高性能-多线程并发编程--1.2.1 JVM内存模拟 ,线程安全可见性, 使用volatile

多线程的问题

  1. 所见非所得
  2. 无法用肉眼检测程序的准确性
  3. 不同的运行平台有不同的表现
  4. 错误很难重现

可见性问题的学习

线程1 和线程2 去看一样的东西, 看上去不一样**
缓存,可能导致暂时的 可见性问题
重排序会导致永久的问题 ,最终使其死循环**

为什么所见非所得

JVM运行时数据区设计 , 多个内存 进行 ,有 公用的 ,私用的 ,之间交互 必然出现问题
这就是内存模型的又来 , 包含了一系列的规范

jre/bin/server 放置hsdis动态链接库
将运行模式设置为-server ,变成死循环

加关键字volatile

启动参数 -client
解决指令重排序导致的可见性的问题

调整设置解决问题
在这里插入图片描述

测试代码

package com.study.volatiletest;

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 VisibilityDemo {
    private volatile boolean flag = true;//位于共享内存

    public static void main(String[] args) throws InterruptedException {
        VisibilityDemo demo1 = new VisibilityDemo();
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                int i = 0;
                // class ->  运行时jit编译  -> 汇编指令 -> 重排序
                while (demo1.flag) { // 指令重排序
                    i++;
                }
                System.out.println(i);
            }
        });
        thread1.start();

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

解释: 优化带来的弊端
在这里插入图片描述
优化后的伪代码
优化一种是如上图,另一种 变成汇编代码 用jitwatch查看

解决这个弊端的方法 : 内存模型(一种开发规范)

内存模型决定了在程序的每个点上可以读取什么值

private volatile boolean flag = true;
加的这个关键字的由来
volatile

Shared Variables 共享变量描述

线程之间共享的内存 叫 堆内存/共享内存 {实例 , 静态字段 ,数组 都在其中}

如果至少一次访问时写 , 那么 对同一个变量访问次(读/写) 是冲突的

规定

在这里插入图片描述

同步的规定

在这里插入图片描述

Happens-before先行发生原则

在这里插入图片描述

volatile关键字

在这里插入图片描述

final 在JMM中的处理

在这里插入图片描述

double和long的特殊处理

代码

import java.util.concurrent.TimeUnit;

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

    public static void main(String[] args) {
        new Thread(new Runnable() {
            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循环
        VisibilityDemo1.is = false;
        System.out.println("被置为false了.");
    }
}
import java.util.concurrent.TimeUnit;

public class VisibilityDemo2 {
    // 状态标识 (不用缓存)
    private volatile boolean flag = true;

    // 源码 -> 字节码class
    // JVM 转化为 操作系统能够执行的代码 (JIT Just In Time Compiler 编译器 )(JVM  --  client   , --server)
    public static void main(String[] args) throws InterruptedException {
        VisibilityDemo2 demo1 = new VisibilityDemo2();
        new Thread(new Runnable() {
            public void run() {
                int i = 0;
                while (demo1.flag) {
                    i++;
                }
                System.out.println(i);
            }
        }).start();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值