酒馆笔记 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就会强制要求每次都去读取这个变量的值,而不是从寄存器优化

    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能