volatile的三大特性:可见性、非原子性、禁止指令重排

以下代码验证volatile的可见性可不保证原子性

可见性代码解释

当自己创建的线程还没有修改num值时,一直在while里面循环,当5秒休眠完成后修改成功,因为可见性,主线程知道已经num修改完毕跳出while循环

不保证原子性代码解释

如果是保证原子性的那么num将会变成20000,实际上会num会比20000少,因为n++的时候被其他的线程打断了,若要保证原子性可以使用AtomicInteger代替。详情请看代码表示

禁止指令重排

指令重排就是java编译的时候如果没有依赖关系的时候,可能会让java的代码编译不按代码所写的顺序去编译,volatile禁止指令重排就是类似于会让各个代码直接增加一个屏障,保证了一种顺序性。

class Number{
    volatile int num = 0;

    public void numTo60(){
        this.num = 60;
    }

    public void numIncrement(){
        num++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    public void addAtomic(){
       this.atomicInteger.getAndIncrement();
    }
}


public class VolatileTest {

    public static void main(String[] args) {
      volatileEnableSee();//可见性验证
      //volatileNotAtomic();//Volatile不保证原子性验证
      // atomicInteger();//AtomicInteger保证原子性
    }

    static void volatileEnableSee(){
        Number number = new Number();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(5);
                number.numTo60();
            }catch (Exception e){
                e.printStackTrace();
            }

        },String.valueOf("A")).start();

        while (number.num == 0){

        }
        System.out.println(Thread.currentThread().getName()+"\t num to " + number.num);
    }

    static void volatileNotAtomic(){
        Number number = new Number();
        for (int i = 0; i <20 ; i++) {
            new Thread(()->{
                for (int j = 0; j <1000 ; j++) {
                    number.numIncrement();
                }
            },String.valueOf(i)).start();
        }
        if (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(number.num);
    }


    static void atomicInteger(){
        Number number = new Number();
        for (int i = 0; i <20 ; i++) {
            new Thread(()->{
                for (int j = 0; j <1000 ; j++) {
                    number.addAtomic();
                }
            },String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+"\t atomic is:"+ number.atomicInteger );
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值