A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package com.test1;
public classDthread {
   public static void main(String[] args) {
      // TODO Auto-generated method stub
      Test1t1 = newTest1();
      Threadth0 = newThread(t1);
      Threadth1 = newThread(t1);
      
      th0.start();
      th1.start();
   }
}
class Test1 implements Runnable{
   private int a=0;
   @Override
   public void run() {
      // TODO Auto-generated method stub
      //下面代码有线程安全问题
      a = a + 1;
      System.out.println(Thread.currentThread().getName()+ "A="+ a);
//    for(inti=0;i<20;i++){
//       a= a + 1;
//       System.out.println(Thread.currentThread().getName()+ "A=" + a);
//    }
   }

}
程序输出的几种结果:
(1)
Thread-0A=1//这种结果10次出现一次,运气好100次出现一次
Thread-1A=1//此结果很奇怪,不应该出现这种问题。需要多次运行才会出现
(2)
Thread-0A=1
Thread-1A=2
(3)
Thread-0A=2
Thread-1A=2
(4)
Thread-0A=2
Thread-1A=1
第(1)种结果很匪夷所思,有线程安全问题,也不应该出现这种数据。两个线程都会执行一次加法,数据是共享的,应该至少有一个线程输出A=2.似乎少计算了一次.
用注释中的for循环输出也会出现这种问题,但只会在开始时都输出A=1,最后结果也只会少计算一次。
我猜测a=a+1这一步是同时进行的,两线程运算时拿到的a都等于0,重复了一次a=0+1.又或者是双核CPU的原因???
我想知道这种问题到底是怎么出现的?
截图:


评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

4 个回复

倒序浏览
我看了一下你的代码,我的解释如下你可以参考一下啊。
当线程Thread-0执行到a = a + 1;这段代码时候停止这时候可以知道a=0,然后Thread-1也开始执行,它进来的时候肯定a还是等于0,所以最后输出的结果有可能是都等于1.

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 目标 于 2014-3-15 18:33 编辑

我觉得可能是和多核处理器有关,a = a + 1;   这条语句可能被多核同时执行了,就是CPU1执行th0,CPU2执行th1,而且是同时开始同时结束的。个人认为,等待高手来解答
回复 使用道具 举报
有木有高手!!!求高手解答。。。
回复 使用道具 举报
  1. class ClassThread {
  2.    public static void main(String[] args) {
  3.       Test1 t1 = new Test1();
  4.       Thread th0 = new Thread(t1);
  5.       Thread th1 = new Thread(t1);
  6.       
  7.       th0.start();
  8.       th1.start();
  9.    }
  10. }
  11. class Test1 implements Runnable{
  12.    private int a=0;
  13.    public void run() {
  14.           while(true){
  15.           synchronized(this){
  16.       a = a + 1;
  17.       System.out.println(Thread.currentThread().getName()+ "A="+ a);
  18.           }
  19.    }
  20.    }
  21. }
复制代码

在执行a=a+1前面加上锁synchronized(this){}就可以避免两个线程同时取1的情况,当其中一个线程执行完毕,a的值改变后,另一个线程开始执行a=a+1操作。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马