volatile关键字的相关学习记录

博客 分享
0 203
张三
张三 2022-02-26 19:55:50
悬赏:0 积分 收藏

volatile关键字的相关学习记录

1:volatile是什么?

Volatile是java虚拟机提供的一种轻量级的同步机制,具有 三大特性,分别是:保证可见性、不保证原子性、禁止指令重排

可见性:

概念:每一个线程都有自己的工作内存,线程不能直接操作主内存的值,必须把主内存的数据拷贝回工作内存进行更改后,刷新回主内存,并及时通知其他线程

import java.util.concurrent.TimeUnit;public class test {    public static void main(String[] args) {        MyData myData = new MyData();        new Thread(() -> {            try {                TimeUnit.SECONDS.sleep(3);            }catch (Exception e){            }            myData.addTo60();            System.out.println(Thread.currentThread().getName() + " update value to 60 :" + myData.number);        },"AAA").start();        while (myData.number == 0){        }        System.out.println(Thread.currentThread().getName() + " get value mydata.number :" + myData.number);    }}class MyData{    /**     * 当加了volatile这个关键字的时候,由于其中一个线程修改完毕 立即通知,那么另一个线程就会收到值被修改,则在上述循环方法中将会跳出 并结束     *      * 如果不加,则其中一个线程将不会收到值被修改的情况,导致while循环将一直存在     */    volatile int number=0;    public void addTo60(){        this.number=60;    }}

 

 

 

不保证原子性:

代码:

import java.util.concurrent.TimeUnit;public class test {    public static void main(String[] args) {        //验证volatile不保证原子性的问题        MyData myData = new MyData();        for (int i = 1; i <= 20; i++) {            new Thread(()->{                for (int j = 1; j <= 1000; j++) {                    myData.addPlusPlus();                }            },String.valueOf(i)).start();        }        //等待执行完成,        while (Thread.activeCount()> 2){            Thread.yield();        }        System.out.println(Thread.currentThread().getName() + " number:" + myData.number);    }}class MyData{    volatile int number=0;    public void addPlusPlus(){        this.number++;    }}打印结果将不可预测

 处理非原子性问题

import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;public class test {    public static void main(String[] args) {        //验证volate不保证原子性的问题        MyData myData = new MyData();        for (int i = 1; i <= 20; i++) {            new Thread(()->{                for (int j = 1; j <= 1000; j++) {                    myData.addPlusPlus();                    myData.addAtomic();                }            },String.valueOf(i)).start();        }        //等待执行完成,        while (Thread.activeCount()> 2){            Thread.yield();        }        System.out.println(Thread.currentThread().getName() + " number:" + myData.number);        System.out.println(Thread.currentThread().getName() + " atomic:" + myData.atomicInteger);    }}class MyData{    int number=0;    public void addPlusPlus(){        number++;    }    AtomicInteger atomicInteger =  new AtomicInteger();    public void addAtomic(){        atomicInteger.getAndIncrement();    }}

 

 

禁止指令重排:

编译器和操作系统会对指令进行优化和重排序,通过volatile可以禁止重排序,主要是在多线程环境下,变量的顺序可能发生变化 从而导致结果不可预测的问题。

代码:单例模式使用volatile方法

import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;public class test {    //双端检索 + volatile 禁止指令重排序    private static volatile test  t  = null;    private test(){        System.out.println(Thread.currentThread().getName() + " test-构造方法!");    }    private static  test getTestInstince(){        if(t == null){            synchronized (test.class){                if(t == null){                    t = new test();                }            }        }        return t;    }    public static void main(String[] args) {        for (int i = 0; i < 10; i++) {            new Thread(() -> {                System.out.println(test.getTestInstince());            },Thread.currentThread().getName() + String.valueOf(i)).start();        }    }}

 

posted @ 2022-02-26 19:36 鸭猪是的念来过倒 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员