由于楼主你没有给这两线程同步,导致线程跑起来就比较随意,啥情况都有可能发生,
你说的就是这种情况:
本来task2将要执行打印task2 :40,结果由于System.out.println(Thread.currentThread().getName() + ":" + i);这句话调用还没结束(执行到一半),线程时间片被task1 抢占了(或者由于到时间了要放弃CPU),但是由于语句没执行完,打印没有输出,i的值是40,线程状态被保存,那么这个值也就被保存了(记住,是40)
好,继续走,轮到task1执行了,执行++i,值增大了1,那么接着打印了task1:41。
完了时间片到了,task2执行,取出上次保存的线程状态,发现i还是40,执行完打印语句(task2:40),又一次循环,这个时候由于task1已经将i的值编程41了,那么task2经过++i后,值变为42,输出打印task2:42
——————这里面最重要的一点就是System.out.println(Thread.currentThread().getName() + ":" + i);这条语句没有执行完,但是i的值作为线程状态被保存起来了,因此下次取到的是个旧值。

解决方案 »

  1.   

    我知道楼主的困惑,你觉得两个线程都共享这一个变量,那这个变量的值不应该顺序是这样。这个时候你要明白,每个线程都有一个线程栈的,为了效率,采用了缓存策略,会将变量拷贝一份到自己的线程栈帧中,这样就没法保证第一时间获取到的是最新更新,或者更新了最新值了。所以这时候如果使用,volatile关键字,就可以避免这种情况发生。如果不明白,欢迎继续提问。可以去看看《java并发编程指南》,就会很清楚了。