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 {        //这里面加不加synchronized 有什么影响?
Thread.sleep(2500);
b= 2000;
  }
  public void run(){
   try{
   m1();
   }catch(Exception e){}
  }
  public static void main(String[] args)throws Exception {
   TT tt = new TT();
   Thread t = new Thread(tt);
   t.start();
  
   Thread.sleep(1000);
   tt.m2();                   //为什么最后挥打印出 b=1000;
   System.out.println(tt.b);  //                 2000;  
  }
}

解决方案 »

  1.   

    如果m2不加synchronized,在m1睡眠时m2就不用等待m1释放锁(sleep时不释放占有的锁)而马上执行并把b设为2000,所以结果总是
    2000
    b= 2000
    但是m2加了synchronized的话,他只能在m1运行好的时候才能运行,所以结果总是
    b= 1000
    2000
      

  2.   

    没错,m2加了synchronized的话,他只能在m1运行好的时候才能运行------------------
    6V信息平台http://www.6vie.com
      

  3.   

    也有可能是你的主线程先获得对象锁,输出结果
    2000 
    b= 2000谁先进入synchronized 方法谁先获得该对象锁,退出该方法释放对象锁
      

  4.   


    1楼正解,简单点说就是用关键字synchronized将要用的变量锁定,因此调用m2的时候b已经被m1锁定,所以方法处于等待状态,而不加synchronized时m2方法就不管b有没有锁定,同理如果m1不加synchronized也就不给b加锁,所以无论m2有没有synchronized都不会等待,因为此时b并没有锁。
      

  5.   

    加了synchronized 结果是
    b = 1000
    2000
    否则得话结果是
    2000
    b= 2000
    加了synchronized 得运行顺序是这样的:
    t线程被启,t线程要执行run方法,那么就会调用ml方法,b得值变成1000,同时对t对象加锁,并且再ml方法中睡眠5秒,睡眠1秒后,主线程继续往下执行,试图执行m2,但是t对象得锁还被t线程占用,不能执行,直到再等待4秒,m1执行结束,即打印初b=1000后,执行m2,此时b改为2000,再打印就是2000了不加synchronized 得运行顺序是这样的:t线程被启,t线程要执行run方法,那么就会调用ml方法,b得值变成1000,但是没有对t对象加锁,睡眠1秒后,主线程是可以调用m2得,这个时候,b已经改成了2000,然后主线程打印出2000,但是由于主线程需要等待子线程结束才可以结束,所以等到m1方式输出b=2000,程序就结束了