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,请各位大侠多多指教,谢谢。
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,请各位大侠多多指教,谢谢。
2件事 如果是 多线程 就是 做 多件 事情
Thread.sleep(2500);着 句话的 意思是 过 2.5秒 在去做 run()方法中的 事
你上面 Thread.sleep(5000); 加上下面的Thread.sleep(2500);
就是 过7.5秒做 run()方法中的 内容
线程启动是需要时间的,而且还需要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了。还是那句话,如果你的机器足够快,你的那个子线程一不小心先拿到了时间片,结果还是会有变动的。 这就是隐患。
m2()启动 sleep
执行 System.out.println(tt.b);这时的b = 1000;
m2() sleep结束 继续执行 b = 2000;
方法加锁后sleep()时方法内的变量拒绝任何访问,直到锁被解除
m1() sleep结束 继续执行 System.out.println("b = " + b); 由于锁没解除 b 还是 1000
而且,方法sleep()后,成员变量并没有被锁住,是还可以访问的。呵呵
我的机器是双核的,运行起来完全是两码事,所以这种问题也不好解决了