日期:2014-05-20  浏览次数:20672 次

一小段关于线程的代码,求高手解释
public class Threads1 {
int x = 0;

public class Runner implements Runnable {
public void run() {
int current = 0;
for (int i = 0; i < 4; i++) {
current = x;
System.out.println(current + ", ");
x = current + 2;
}
}
}

public static void main(String[] args) {
new Threads1().go();

}

public void go() {
Runnable r1 = new Runner();
new Thread(r1).start();
new Thread(r1).start();
}
}

我认为运行结果是0,2,4,6,8,10,12但是我的机子上跑出来是0,2,4,6,0,2,4,6,有人能告诉我应该怎么样去正确地理解这段代码么,不是只有一个Thread1对象么
thread java

------解决方案--------------------
哦。更正一下, 变量x是共享数据。
刚才没注意看程序。

共享数据,没有进行读写保护,所以产生,数据不同步的现象。

所以,其实,任何情况都有可能发生的。

至于楼主说的那种情况,很可能是:
1.两个线程同时进入run方法;
2.当运行至输出语句是,由于System.out对象的print方法,属于IO操作,这个对象发生竞争;
3.有一个线程得到System.out对象的锁,进行输出操作;另一个线程被阻塞直到锁被释放;
4.得到锁的线程进行输出,首次输出为0,释放锁;
5.释放锁后,当前线程进行后续代码的执行,进入下次循环;另一个线程被唤醒,进入就绪状态;
6.进入就绪状态的线程,在没有分到时间片的时候,是没有运行机会的;
7.输出0的线程,由于时间片没有用完,进入循环,进行输出,由于另一线程没有运行机会,所以,没有再次进行锁竞争;
8.4次循环,估计在一个线程时间片内是能够搞定的,所以,谁先输出的0 ,谁就会吧后面的2,4,6输完;
9.一个线程输出完毕后,退出,另一线程得到运行机会,进行输出,由于这个线程是锁竞争被阻塞的,所以,代码要从输出语句开始执行,并且,阻塞前current是0,所以,后面也会输出2,4,6

------解决方案--------------------
楼主,我想了好久,应该是这样的。
0,2,4,6,0,2,4,6,这种情况:
首先这是对同一个对象进行操作的两个进程,Thread[Thread-0,5,main]和Thread[Thread-1,5,main],首先Thread-0获得CPU,当第八行运行完毕后突然被中断了,此时current就是0,被存储了下来。然后Thread-1获得CPU,这个线程全部执行完毕打印出0,2,4,6, ,这时候才轮到Thread-0继续执行,此时current是上次运行时保存下来的0,所以打印0,2,4,6.

而0, 2, 4, 6, 8, 10, 12, 14, 这种情况:
首先Thread-0执行完毕,打印出0,2,4,6, 然后是Thread-1执行打印出0,2,4,6,  

其实可能性很多,主要看线程合适被中断。