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

线程锁的问题 不太清楚线程执行过程
代码:
public class TT  implements Runnable {
   int b=100;
   
    public  void m1 () throws InterruptedException {
b=1500;
Thread.sleep(5000);
System.out.println("b3="+b);
}

     public void m2() throws InterruptedException {
b=2500;
Thread.sleep(2500);
System.out.println("b2="+b);
}
 

@Override
public void run() {
// TODO Auto-generated method stub

try {
m1();
} catch (Exception e) {
// TODO: handle exception
  e.printStackTrace();
}

}
    



public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
        TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println("b1="+tt.b);
}
}
输出结果: b2=1500,b1=1500,b3=1500  问题1:谁能具体解析下具体代码的执行过程,为什么m2()要先m1()执行?

问题2:同时在m1(),m2()前加锁,加关键字 synchronized  输出结果b2=2500,b1=2500,b3=1500 ?? 

问题3:分别给m1(),m2() 单独加锁,结果b2,b1,b3都是1500 ??  
谢谢,希望大牛能给点解析,具体怎么执行。

------解决方案--------------------
引用:
代码:Java code?1 public class TT  implements Runnable {
   int b=100;
   
    public  void m1 () throws InterruptedException {
b=1500;
Thread.sleep(5000);
System.out.println("b3="+b);……


第一问题: 

       m2()是否先与m1()开始执行是无法确定的!这个问题不深究
     但是从你的输出可以看出事m2中的b=2500是先于m1中的b=1500执行的
    之后b=1500了,但是由于sleep(5000),程序执行到tt.m2(),而m2只是sleep(2500)因此m2方法先执行首先输出b2=1500
之后程序顺序执行到System.out.println("b1=" + tt.b);输出b1=1500
最后执行m1()输出b3=1500
     tips:它们的输出顺序和你睡眠时间有关,但是b的值是一样的!
    无非都是1500或则2500,


第二个问题:由于你是锁的方法而非对象,且m1、m2都加了锁形成了同步方法
   线程在执行同步方法时是具有排它性的。当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出。
    这里m2方法抢先执行此时m1被锁住b=2500;
首先输出b2=2500;之后执行到System.out.println("b1="+tt.b);同样输出b1=2500
最后执行m1,b3=1500,输出b3=1500


第三个问题:
     单独加锁:在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。
也就是说,单独加锁的情况和第一种情况是一样的!




------解决方案--------------------
个人浅见:
1 关于m2()先于m1()执行,是因为t线程启动后,要等待虚拟机的调度,而m2()就在主线程里运行,(已经在运行了)所以通常是m2()先于m1()运行。m2先执行,会给b赋值2500,但马上休眠了,这会m1会执行,就给b复制1500了,最后输出的都是这个值。

2 关于问题2,m1(),m2()都加上synchroniezd关键字,根据上面1 的分析,m2()先执行,因为加了同步,所以在m2()执行时,t线程是在等待状态,m1()不会执行。m2()执行完后,会输出b2=2500. 但接下来输出可能是b1=2500,也可能是b1=1500. 这块是随机的!  因为m2()执行完后,同步锁释放,m1()会运行,但同时主线程也会继续执行,具体哪个先执行,就无法确定了。如果m1()先执行,会输出b1=1500; 反之会输出b1=2500. 最后b3=1500.

3 问题3,分别加锁就和没加一样,所以输出和1 一样。
------解决方案--------------------