SE8-高并发问题-volatile 不能解决 非原子性

package com.itheima._4volatile;

public class MyThread2 extends Thread{
    public static volatile int money = 0;//volatile 不能让变量是一个原子操作了
    @Override
    public void run() {//run方法不让抛异常throws//父类和子类异常最好保持一致
        for (int i = 0; i < 100; i++) {

            try {
                Thread.sleep(10);//休眠
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            money++;
        }
    }
}

package com.itheima._4volatile;

import com.itheima._3非原子性.MyThread;

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        MyThread my = new MyThread();
        my.start();
        for (int i = 0; i < 100; i++) {
            Thread.sleep(10);//两个线程总共 花费时间是1秒
            MyThread.money++;
        }

        //等待(休眠)2秒 输出结果
        Thread.sleep(5000);
        System.out.println("总额:"+MyThread.money);//总额:146
    }
}

Volatile

1. 解决非可见性的问题

原理:

  • 加了volatile的变量,一旦修改强制变量副本失效

  • 各个使用该变量的线程,重新获取主内存的新值

public static volatile int a = 1;//加上volatile关键字就可以了

2. 解决非有序性的问题

原理:

  • 不会让编译的字节码文件进行重排。

  • 不会造成由重排所导致的数据不一致情况。

3. 不能解决非原子性的问题

无法解决原子操作问题

i++是不是原子操作 ?

/*
   i++ 不是一个原子操作;也就是说i++不是一个整体,不是不可分割,它是分三步:
*/
   1. 获取 i的值
   2. i + 1
   3. i + 1 后的值 赋值给 i
//以上每一步都有可能失去cpu执行权,被其他线程抢过去
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值