t.start();然后调用 run(),执行m1();由于该方法是synchronized同步方法,所以t线程将拥有对象tt的内部锁,此时如果该内部锁不被释放(m1方法执行完),tt.m2();方法是不能被执行(同步方法的限制)。然后其中,sleep方法只是计时等待,并不会释放所持有的锁,故线程t一直拥有着tt对象的内部锁(即使调用了5秒sleep),直到方法执行完(执行期间就system.out输出b了,b=1000),然后主线程才执行m2方法。这块楼主要明白,
1.synchronized方法的原理和使用,一旦一个线程执行了一个对象的同步方法,其他线程是不能再执行该对象的所有同步方法的。
2.sleep方法只是进入计时等待,并不释放锁,时间一到就继续执行下去。而想要释放锁,就要用wait方法。
1.synchronized方法的原理和使用,一旦一个线程执行了一个对象的同步方法,其他线程是不能再执行该对象的所有同步方法的。
2.sleep方法只是进入计时等待,并不释放锁,时间一到就继续执行下去。而想要释放锁,就要用wait方法。
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception {
System.out.println("执行m1()方法 " );
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
System.out.println("执行m2()方法 " );
Thread.sleep(2500);
b = 2000;
System.out.println("b = " + b);
} public void run() {
System.out.println("执行run()方法 " );
try {
m1();
} catch(Exception e) { e.printStackTrace(); }
}
public static void main(String args[]) {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
try{
tt.m2();}
catch(Exception e){
e.printStackTrace();
}
}
}程序的执行过程如下:
执行m2()方法
执行run()方法
b = 2000
执行m1()方法
b = 1000分析:
由此可见程序首先执行的是m2()方法,然后是run()方法,最后是m1()方法。所以当执行 tt.m2();时,内部的实际过程是先执行了调用的方法,其次才执行线程的run()方法,而在run()方法中又调用执行了m1()方法
实际上,m1,m2是各自独立的动作,用锁回避了并发冲突。
只是谁先谁后其实是不确定的,楼主可以在m2当中加上打印。
然后在main当中,每5秒钟循环做一次原main的动作,就会知道了:主线程和子线程谁先被执行是不确定的。
1;
2;
}等价于如下形式:public void add(Object obj){
synchronized(this){
1;
2;
}
}因此,假如你的m1方法拿到当前对象的锁标记后执行赋值并sleep(继续持有锁标记),此时m2方法也需要当前对象的锁标记,但是拿不到,因此不会造成并发冲突。
这里还有个问题,如4楼所说,主线程 和 t线程的执行顺序是不确定的,只是t线程先拿到时间片抢先执行的可能性更大
wait会释放锁知道被 notufy楼主应该是这两个概念没弄清楚吧http://blog.csdn.net/liyantianmin/article/category/2735267
可以看看