JUC并发编程Vaolatile(十七)

JMM

什么是JMM?

JMM:java内存模型,不存在的东西,概念, 约定

关于JMM的一些同步的约定

1.线程解锁前,必须把共享变量立刻刷回主存

2.线程加锁前,必须把读取主存中的最新值得工作内存中

3.加锁解锁是同一把锁

 

 

扫描二维码关注公众号,回复: 11782395 查看本文章

 Volatile是java虚拟机提供的轻量级同步机制

1.保证可见性

package com.xizi.volatie;

import java.util.concurrent.TimeUnit;

public class JMMdemo {
    //不加 volatile 程序就会死循环
    //volatile 可以保证可见性
    private volatile static int num=0;
    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            while (num==0){

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

2.不保证原子性

原子性:不可分割

线程A在执行任务得时候,不能被打扰,也不能被分割。要么同时成功,要么同时失败

package com.xizi.volatie;

public class Volatiledemo2 {
    // volatile 不保证原子性
    private volatile static int num=0;
//synchronized  20000
    public  static void add(){
        num++;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                for (int i1 = 0; i1 < 1000; i1++) {
                    add();
                }
            }).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println( num);
    }
}

 如果不用Lock 和synchronized, 怎么保证原子性

使用原子类 解决原子性问题

package com.xizi.volatie;

import java.util.concurrent.atomic.AtomicInteger;

public class Volatiledemo2 {
    // volatile 不保证原子性
    private volatile static AtomicInteger  num=new AtomicInteger();
//synchronized  20000
    public  static void add(){
//        num++;//
        num.getAndIncrement();// 方法:CAS   AtomicInteger +1
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                for (int i1 = 0; i1 < 1000; i1++) {
                    add();
                }
            }).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println( num);
    }
}

 这些类得底层和操作系统挂钩 ,在内存中修改值,Unsafe类是一个很特殊得存在

3.禁止指令重排

 源代码-->编译器优化的重排-->指令并行也可能重排-->内存系统也会重排-->执行

处理器在进行指令重排的时候 考虑数据之间的依赖性

valatile避免指令重排:

内存屏障,CUP指令 作用

1.保证特定的操作的执行顺序

2.可以保证某些变量的内存可见性

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/105383307