请看如下代码:
开启两个线程对count执行加运算,按道理两个线程运行完以后,count不是应该加了2000000次吗?怎么结果打印没有200000呢?public class ThreadDemo { class RunnableImpl implements Runnable{
int count=0;
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<100000;i++){

count++;

System.out.println(Thread.currentThread().getName()+":"+count);
}
}

}
public static void main(String[] args) {
ThreadDemo demo=new ThreadDemo();
RunnableImpl impl=demo.new RunnableImpl();
Thread t1=new Thread(impl,"线程1");
Thread t2=new Thread(impl,"线程2");
t1.start();
t2.start();
}

}多试几次,结果都不尽相同,反正想了解为什么结果count没有200000.
高手请指教!

解决方案 »

  1.   

    应该在run方法里加个同步代码块
      

  2.   

    多个进程同时访问一个公共资源,可能会造成公共资源破坏
    在某一时刻,两个进程同时对count加一,加之前count假设是20,加一之后就是21
    本该是22的,但是结果就是21,以后也有可能发生类似事件,所以造成结果不是200000,而且结果肯定不大于200000
      

  3.   

    两个线程争用同一个count对象当然会出问题的,程序这样改有没有问题了:synchronized public void run() {
      

  4.   


    不是说cpu对线程的调度遵循时间片轮转原则,在某一时刻只是一个线程在运行吗?那怎么会出现两个线程同时对count加一呢?
      

  5.   

    这篇文章或许能解释 http://zhidao.baidu.com/question/224640172.html
      

  6.   

    当然不会有,你是对impl实例起了两个线程在跑,这个时候count是共享的。也就是说你把count++交给两个线程去做了,当然不会有200000次啊。
      

  7.   


    或许是这样吧,可是我就是想搞清楚为什么把count++交给两个线程去做,就不会有200000呢?能详细点告诉吗?谢了。
      

  8.   

    楼主,我考虑了一下,应该会存在这种概率
    for(int i=0;i<100000;i++){//打个比方,当i等于100时,这个条件两个线程是不是可以同时满足?
    线程1比较积极,先执行了i++语句。变成101。线程2开了个小差,又执行了一把i++。这无形中就少了一次循环
     count++;
     System.out.println(Thread.currentThread().getName()+":"+count);
     }
      

  9.   

    因为count为RunnableImpl类的成员变量(类变量),线程t1和t2使用的是同一个RunnableImpl类的实例impl,所以内存中只有一个count变量的拷贝,那线程t1和t2就有可能同时在对count进行读写操作,互相把对方的值给冲掉了,所以有可能你跑10次,10次的count的结果都不一样,但是都是小于20000的值,在线程中对这种只有一个内存拷贝的变量进行操作时可以使用synchronized块来解决共享冲突问题,你试一下这样,得到的结果应该就是20000了,当线程t1和t2的其中一个进入synchronized块后,另外一个线程会在外面等待,直到之前进入的那个线程出来后才会进去,这样就会有一个读写count的先后次序,不会发成冲突了:for(int i=0;i<100000;i++){    synchronized(count) {
            count++;
            System.out.println(Thread.currentThread().getName()+":"+count);
        }
    }
      

  10.   

    使用java.util.concurrent.atomic.AtomicInteger :
    // ...
    // int count=0;
    AtomicInteger count = new AtomicInteger(0);
    // ...
    // count++;
    count.getAndIncrement();
    // System.out.println(Thread.currentThread().getName()+":"+count);
    System.out.println(Thread.currentThread().getName()+":"+count.get());
      

  11.   

    run 方法里加同步
    因为两个线程在操作同一个变量啊
      

  12.   

    这是线程安全的问题,你在你的循环里面放一个 Thread.sleep(1000); 每次循环暂停1秒,你就会发现问题了。