chenzhichao 2015-08-03 16:30 采纳率: 50%
浏览 4114
已采纳

java多线程操作同一个变量的问题,难道是多核cpu所致?

大家请看代码和输出结果,我百思不得其解,为什么 amount只加了一次,开始我以为是static所致,就算去掉也还是有几率出现这样的结果,难道是多核cpu真的把两个线程同时执行了?图片说明

package study;

public class MyRunnable implements Runnable {

    public static int  amount=0;
    @Override
    public void run() {
        // TODO 自动生成的方法存根
        amount++;
        String s=Thread.currentThread().getName();
        System.out.println(s+"  "+amount);
    }
}
package study;

public class MyFirstThread {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
         MyRunnable r1=new MyRunnable();
     Thread AThread=new Thread(r1);
     Thread BThread=new Thread(r1);
     AThread.start();
     BThread.start();

  for(;;)
  {
      if((!AThread.isAlive())&&(!BThread.isAlive()))
      {
        System.out.println("amount ="+r1.amount); 
        break;
      }
  }

    }
}

  • 写回答

6条回答 默认 最新

  • danielinbiti 2015-08-03 16:36
    关注

    没有加同步锁的问题,两个线程是同时执行的,amount什么值都有可能,可能都是1,可能打印都是2,也可能打印2,1。所以需要对amount加同步锁

     public static Integer  amount=0;
        @Override
        public void run() {
            // TODO 自动生成的方法存根
            synchronized(amount){
                amount++;
                String s=Thread.currentThread().getName();
                System.out.println(s+"  "+amount);
            }
        }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • gldzkj 2015-08-03 16:37
    关注

    对,单核时代,同一时刻,只有一个执行,现在多核时代了

    评论
  • threenewbee 2015-08-03 22:18
    关注

    晕,线程没有同步,无论单核多核都需要线程同步。这是起码的常识。

    评论
  • Yanphet 2015-08-04 00:25
    关注

    无论单核多核都不是同步执行的,CPU在各个线程随机执行(优先级高的线程得到CPU执行的机会更多),你所看到的同步,其实是CPU在线程之间切换执行,只是速度太快,我们无法跟上。

    评论
  • threenewbee 2015-08-05 22:29
    关注

    如果只有一个处理器,仍然可能出现线程同步的问题,和什么多cpu同时执行没有关系。

    我再说清楚一些

    这是因为amount++;不是原子化的操作,它是这样的
    int x = amount;
    x = x + 1;
    amount = x;
    (这里x代表寄存器,amount代表内存)
    我们假设你只有1个cpu,也就是执行本身不是并发的,但是有两个线程

    假设amount = 0
    线程1
    int x = amount;
    此时x = 0, amount=0
    切换到线程2
    注意,x是寄存器,每个线程独立,而amount是共享的,只有一个,所以为了避免混淆,这里x写成x1表示另一个变量
    int x1 = amount;
    此时x1=0 amount=0
    x1 = x1 + 1;
    此时x1=1
    再切换到线程1
    x = x + 1;
    amount = x;
    此时x = 1
    amount=1
    再切换到线程2
    amount = x1;
    记住,x1=1
    所以amount=1
    结果是1而不是2
    为什么这样?因为x存的数据是脏数据,amount被另一个线程更新了,但是x没有更新。
    注意,以上代码不是并行执行的,同样有同步问题。

    评论
  • MagicIcesea 2015-08-06 14:53
    关注

    可以看看龙书的线程同步,讲的十分仔细。 《operating system concepts》

    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥30 矩阵分析与古诗词意境
  • ¥15 在win10 64位的vs打包MSI文件,放到win7 64位上安装成可执行exe文件后,点击程序不运行。
  • ¥50 大众点评用户浏览/消费记录爬虫
  • ¥15 求制作一个个人网页,
  • ¥15 寻涂色内存脚本作者有项目有市场有资源.却技术
  • ¥15 蓝桥杯c51单片机问题
  • ¥15 ajax跨域问题请求修改代码
  • ¥15 python matplotlib
  • ¥15 短信测压+语音,有偿,必须用Python
  • ¥20 COCOS2DX的protobuf协议注册函数问题