java的内存模型(概念)

在java中,设计之初就有了:主内存、线程工作内存,所以其实每一个线程执行时,都是将主线程copy一份到工作线程,执行修改后,再同步回去。

java的内存模型(概念)_第1张图片

所以,就有四组内存操作方式:

1、主内存,加载到工作内存

2、 通过执行引擎使用工作内存数据、修改工作内存

3、读工作内存、写到主内存

4、使用内存时会:加锁,解锁

 volatile可以让多个线程可见,或者说不再操作工作内存

package com.quxiao.controller;


import java.sql.Time;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.*;
import java.util.stream.LongStream;

/**
 * @program: package1
 * @author: quxiao
 * @create: 2023-09-27 15:22
 **/
public class t3 {
    static volatile int sum = 0;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (sum == 0) {

            }
            System.out.println(1);
        }).start();
        TimeUnit.SECONDS.sleep(1);
        sum = 1;
    }
}

但是使用了volatile就没有了原子性,也就是线程操作不再唯一,例如:

A线程取出时为10,正准备+10,数据变成了15,结果就成了15+10。

指令重排(很神奇的一个东西)

package com.quxiao.controller;


import java.sql.Time;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.*;
import java.util.stream.LongStream;

/**
 * @program: package1
 * @author: quxiao
 * @create: 2023-09-27 15:22
 **/
public class t3 {
    static int x = 0;
    static int y = 0;
    static int a = 0;
    static int b = 0;

    public static void main(String[] args) throws InterruptedException {
        //大致如此,但是
            new Thread(() -> {
                x = a;
                b = 1;
            }).start();
            new Thread(() -> {
                y = b;
                a = 2;
            }).start();
        //有可能x=2,y=1
        System.out.println(x + ":" + y);
    }
}

x=b和a=1这两句话完全没有关联,编译器就有可能把他俩重新排顺序。(上面的代码只是理论,其实很难遇到)

加上volatile,就能解决,多了两层内存屏障:

java的内存模型(概念)_第2张图片

你可能感兴趣的:(多线程,java,开发语言,jvm)