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

问大家一个关于线程同步synchronized 的问题?
package com.bjsxt.thred ;
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception{
b = 1000;
Thread.sleep(1000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
System.out.println(b);
}
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("a =" + tt.b);
}
}
//为什么这段代码的最后输出是:
//2000
//a =2000
//b = 1000
//关于线程同步的执行先后问题,有点头大啊,哪位大神,帮忙解释一下呢?


我怎么感觉b = 1000 应该先打印啊。。
我把程序改动改动,发现一个问题 ,不管谁先输出,a = 2000总是跟第一句话同时打印,总是在第二句打印,这是为什么呢?小弟不才~~!!




------解决方案--------------------
m1() 和 m2() 谁先抢到锁谁就先执行,由于m2在主线程中执行,所以它执行完了,后边的System.out.println("a =" + tt.b);才能执行到,这就是它总是跟在m2打印结果后边的原因
------解决方案--------------------
t.start()创建了一个新的线程,但是主线程依旧在往下执行,主线程进入synchronized方法比t早,(这个无法解释,可能是语句过多??高手指点)tt.m2()是一个被synchronized修饰的方法,这个方法只要有一个线程访问,那么被synchronized的其它方法就不能同时执行,所以在tt.m2()执行完了以后t.start()中调用的m1方法开始执行,其中有个sleep()所以主线程的System.out.println("a =" + tt.b);先输出
------解决方案--------------------
在main方法中现在有两个线程,一个是新建的t另外一个就是主线程,在t.start()时,主线程仍在向下执行,主线程先执行到被synchronized修饰的方法,如果有多个方法被synchronized修饰时,如果有一个方法在执行,那么其它线程不能同时访问这个对象中任何一个synchronized方法,所以t.start()在执行m1()之前,主线程已经执行m2(),t只能等待,在m2()执行完后m1()开始执行,由于m1中有sleep方法,所以m1的输出语句比主线程的输出语句System.out.println("a =" + tt.b);晚。
------解决方案--------------------
在m1中,调用了sleep方法,此时m2抢到执行权,进入m2,b=2000执行,执行System.out.println(b);输出2000.然后执行主线程中的System.out.println("a =" + tt.b);因此输出a=2000
------解决方案--------------------
引用:
在main方法中现在有两个线程,一个是新建的t另外一个就是主线程,在t.start()时,主线程仍在向下执行,主线程先执行到被synchronized修饰的方法,如果有多个方法被synchronized修饰时,如果有一个方法在执行,那么其它线程不能同时访问这个对象中任何一个synchronized方法,所以t.start()在执行m1()之前,主线程已经执行m2(),t只……

晕,网络一直出问题,回复了这么多
------解决方案--------------------
我的一点见解,请各位大虾指教
程序执行的顺序可以从这三句开
t.start();
tt.m2();
System.out.println("a =" + tt.b);

下面逐句分析:
t.start();
表示线程启动,但是启动不是代表马上就执行run()里的语句(操作系统决定)
所以:
tt.m2();
得到执行,由于m2是同步方法,所以进入后锁定当前对象this,拿到锁了
m2进入睡眠,这时m1可能已经得到时间片了,开始执行了,由于m1也是
同步方法,所以它必须先拿到锁,但是锁已经被m2先拿到了,所以它必须等待
m2执行完才能够继续执行,故:
首先输出:2000
m2执行完毕,现在有2条路,第一条是m1要执行,第二条是main要继续执行
到底谁先执行,还是操作系统说了算,
如果main先,那么输出:a = 2000 ,然后m1执行输出 b=1000
如果m1先,那么b=1000,m1睡眠,继续main执行,故输出:
a=1000   b=1000





------解决方案--------------------
public class ThreadTest implements Runnable {
int b = 100;

public synchronized void m1() throws Exception {