public class TT implements Runnable {
int b = 100;

public synchronized void m1() throws Exception{
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}

public synchronized void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}

public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();

tt.m2();
System.out.println(tt.b);
}
}以上代码,输出的结果为:1000 
                    b = 1000
问题1:在main方法中为什么执行顺序会是先执行完tt.m2()方法后,再执行线程的t1()方法,最后执行System.out.println(tt.b)?
既然是多线程,为什么不能先t1()方法,再执行tt.m2()方法,最后在执行System.out.println(tt.b)?问题2: 如果把m2()方法的Thread.sleep(2500)去掉,其输出结果为:2000
                                                         b = 1000
其执行过程又是怎样?本人初学java,请各位大侠多多指教,谢谢。

解决方案 »

  1.   

    Thread.sleep(2500); 是放在 run()方法中的 因为线程 是调用 run()方法后 同时 工作
    2件事 如果是 多线程 就是 做 多件 事情
    Thread.sleep(2500);着 句话的 意思是 过 2.5秒 在去做 run()方法中的 事
    你上面 Thread.sleep(5000); 加上下面的Thread.sleep(2500);
    就是 过7.5秒做 run()方法中的 内容
      

  2.   

    请注意一个问题
    线程启动是需要时间的,而且还需要CPU分配时间片给他TT   tt   =   new   TT(); 
    Thread   t   =   new   Thread(tt); 
    t.start(); // 通知线程可以启动了,当不一定现在就归他,如果你的机器够快,CPU够多,也不排除t里面的先运行后,再运行下面这一句tt.m2();  // 在绝大多数情况下,这句和上一句之间被分配给前面线程的几率就高多了,所以这个先被执行的几率要高
    System.out.println(tt.b); tt.m2 里面一但sleep, 则线程就拿到了时间片,但他也马上sleep了,而且比主线程的长,结果主线程先觉醒了。
    由于线程秀面前更改了b=1000, 所以主线程打印时等于1000了如果主线程没有sleep, 同前面的理由,主线程继续运行的几率要非常高,所以b=2000, 打印出2000了。还是那句话,如果你的机器足够快,你的那个子线程一不小心先拿到了时间片,结果还是会有变动的。 这就是隐患。
      

  3.   

    m1()先启动 b被赋值为1000  sleep
    m2()启动 sleep
    执行  System.out.println(tt.b);这时的b = 1000;
    m2() sleep结束 继续执行 b = 2000;
    方法加锁后sleep()时方法内的变量拒绝任何访问,直到锁被解除
    m1() sleep结束 继续执行  System.out.println("b = " + b); 由于锁没解除 b 还是 1000
      

  4.   

    楼上的解答有些问题把?m2()执行的时候主线程sleep 就不继续往下执行了。因此主方法里面也不会再打印。直到睡眠结束,继续执行b =2000 再打印。
    而且,方法sleep()后,成员变量并没有被锁住,是还可以访问的。呵呵
    我的机器是双核的,运行起来完全是两码事,所以这种问题也不好解决了