public class Machine implements Runnable{
  private int a=0;
  public void run(){
    for(a=0;a<50;a++){
      System.out.println(Thread.currentThread().getName()+":"+a);
      try{
        Thread.sleep(100);
      }catch(InterruptedException e){throw new RuntimeException(e);}
    }
  }
  public static void main(String args[]){
    Machine machine=new Machine();
    Thread t1=new Thread(machine);
    Thread t2=new Thread(machine);
    t1.start();
    t2.start();
  }
} 这个打印结果为什么a=0有2次?

解决方案 »

  1.   

        Machine machine=new Machine();
        Thread t1=new Thread(machine);
        Thread t2=new Thread(machine);首先他们还没开始的时候。t1、t2首先拿的都是machine这个对象中的a 的值。
    所以这个时候如果往外打印,肯定都是0了。当他们都开始循环的时候,就开始一个一个累加了。并且这里a是machine的。
    所以2个线程对一个线程变量累加(说多了。、)楼下反编译一个。
    有的告诉我。。
      

  2.   

    两个线程实例,在这里System.out是个共享资源,一个线程打印了0,后睡眠,另一个线程依然从0开始打印,所以两次,以后的数,比如第一个线程打印了45,下次for循环,它应该打印46,但它打印时,System.out已有另一个线程使用,不能执行,它继续for循环(另一个线程睡眠),它打印47,如此推理
      

  3.   

    楼主这段代码只是说明了线程的并发执行而已
    至于为什么一开始输出的是两个0:
    “一个线程打印了0,后睡眠,另一个线程依然从0开始打印,所以两次。”
    这也是二楼说的,不过二楼后半部分说法感觉有点问题
    因为你的代码根本就没有涉及到线程互斥
    后续的输出无法预测,甚至有些a的值打印不出来
    要互斥必须加锁public class Machine implements Runnable{
      private int a=0;
      private Object object=new Object();
      public void run(){
      synchronized (object) {
      for(a=0;a<50;a++){
          System.out.println(Thread.currentThread().getName()+":"+a);
          try{
            Thread.sleep(100);
          }catch(InterruptedException e){throw new RuntimeException(e);}
        }
    }
        
      }
      public static void main(String args[]){
        Machine machine=new Machine();
        Thread t1=new Thread(machine);
        Thread t2=new Thread(machine);
        t1.start();
        t2.start();
      }
    }
      

  4.   

    第一个线程进来后,a=0,然后打印出来0,接着睡了0.1秒。这个时候for代码块里面的a还没来得及+1,第2个线程进来了,依然从0开始。问题就出在a++这里被第2个线程打断了。
    for(a=0;a<50;a++){
          System.out.println(Thread.currentThread().getName()+":"+a);
          try{
            Thread.sleep(100);
          }catch(InterruptedException e){throw new RuntimeException(e);}
        }
      

  5.   

    System.out是个共享资源,代码并没有同步,当一个线程通过System.out.println()开始写入时,可能还没有结束写入,就有另一个线程插入进来,开始写入它的输出。哪个线程会抢先于另一个线程,具体顺序是不能确定的,每次运行代码,会有略微不同的输出,这本代码中,睡眠0.1秒,只是让其他的线程有机会运行,所以打印结果也与它有关
      

  6.   


    顶四楼,前几天刚看了资料,就是这样解释的。因为你的共享资源没有加锁,cpu对线程的切换时随机的,它是以语句为单位,随时都有可能中断去执行另外的线程。