酒馆笔记 2017-03-28 08:55 采纳率: 25%
浏览 834

线程不安全方法,取同一个内存区数据,取到同一个数据是为什么

今天通过视频学习线程并发,测试的时候发现线程不安全的方法,取数据时,会取到大量相同的数据。我知道线程不安全可能会取到错误的数据,但是为什么会发生上述情况呢,是因为cpu么。求大神简单解释原理

/*模拟网络12306抢票概念流程*/
 public class SleepDemo02 {

    public static void main(String[] args) {
        //真实角色
        web12306 web=new web12306();
        //代理角色
        Thread t1=new Thread(web,"大黄牛");
        Thread t2=new Thread(web,"小黄牛");
        Thread t3=new Thread(web,"老黄牛");
        t1.start();
        t2.start();
        t3.start();
    }

}
class web12306 implements Runnable{

    private int num=50;
    @Override
    public void run() {

    while(true){
        if(num<=0){
            break;
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
    } 
    }

}

关键运行结果:
老黄牛抢到了50
小黄牛抢到了49
大黄牛抢到了50
小黄牛抢到了48
老黄牛抢到了48
大黄牛抢到了47
小黄牛抢到了46
老黄牛抢到了46
大黄牛抢到了45
老黄牛抢到了44
小黄牛抢到了43
大黄牛抢到了42
老黄牛抢到了41
小黄牛抢到了40
大黄牛抢到了39
小黄牛抢到了38
老黄牛抢到了37
大黄牛抢到了36
小黄牛抢到了35
老黄牛抢到了35
大黄牛抢到了34
小黄牛抢到了33
老黄牛抢到了33
......

  • 写回答

2条回答 默认 最新

  • oyljerry 2017-03-28 09:11
    关注
     private volatile int num=50;
    

    主要是寄存器优化,你不加volatile,当多线程去读取这个变量的时候,会从寄存器中读取这个值给你,而它可能是一个旧值,也就是其他线程修改了,你不会马上读取到。而加了volatile就会强制要求每次都去读取这个变量的值,而不是从寄存器优化

    评论

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办