public class TT implements  Runnable{
  int b=100;
    
  public synchronized void m1(){
  b=1000;
  try{
  Thread.sleep(5000);
  }catch(Exception e){
  e.printStackTrace();
  }
  System.out.println("b="+b);
  }     public void m2(){
  b=2000;
  try{
  Thread.sleep(2500);
  }catch(Exception e){
  e.printStackTrace();
  }
  }   public void 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();
  tt.m2();
  System.out.println(tt.b);
  }
}如果是上面这种情况,m2方法不加synchronized 这个时候执行的方式是这样的:主线程新建了一个tt对象,然后主线程 Thread t = new Thread(tt)创建了一个t线程,
t.start();这个时候t线程是处于可执行状态,但是有没有得到CPU的时间片还不知道,可能得到也可能没有得到,1、如果得到了时间片,就执行run()方法,然后执行
m1()方法,将b的值改为1000,然后t子线程睡着了,主线程开始执行,主线程执行tt.m2()方法,为什么这个方法会被执行,因为synchronized只能锁对象,但是不能锁
对象的方法,因为m2方法不是同步方法,所以可以被执行,b的值改为2000,然后主线程睡2.5秒,这个时候主线程会先醒,然后执行打印打印出b的值为2000,然后tt子
线程会醒,这个时候b的值为2000,但是我在机器上得到的值都是1000,我分析哪点错了?2、如果t线程没有得到时间片,这个时候不会马上进入run()方法,主线程就会
顺序执行,这个时候会调用tt.m2()方法,这个时候将b的值改为2000,然后主线程睡了2.5秒,打印tt.b的值为2000,然后t子线程执行run()方法,调用m1()方法,将b的值
改为1000,这个时候t线程睡5S 然后打印b=1000,但是我试了 结果只有可能是1000,b=1000,不知道我哪里错了??我被synchronized这个词搞郁闷了,如果在m2方法
上加synchronized,这个时候是怎么执行的,请大牛们帮帮小弟的忙谢谢了!!!!请大牛写的详细点,线程不是很懂,一两句我觉得我很难理解

解决方案 »

  1.   

    如果某个类的某个方法加了synchronized就会锁住这个对象,如果该对象内有其他的synchronized方法要执行就要等待上一个synchronized方法执行完毕,但是非synchronized方法仍然可以执行。
      

  2.   

    如果某个类的某个方法加了synchronized就会锁住这个对象,如果该对象内有其他的synchronized方法要执行就要等待上一个synchronized方法执行完毕,但是非synchronized方法仍然可以执行。这个我知道啊,我想问的是上面的程序怎么执行的,详细点,然后就是如果讲m2方法加了synchronized会有什么效果,也分析分析。
      

  3.   

    看见一个人说m2方法加了synchronized以后,他是这样分析的
    ①t.start();
    ②tt.m2();
    ③System.out.println(tt.b);
    主要是这里不懂吧,告诉你,main执行到①时,有两种可能,一种是立即启动,一种是准备好,但是不启动,如果是立即启动,那么b=1000,然后睡眠5000个毫秒,这时候执行③,然后待5000个毫毛睡眠完毕后继续执行 结果是b=1000,第二种可能是准备好,不执行,那么②就开始执行,直到b被赋值为2000后,这时候又分两种可能,第一种可能是执行①,那么b又被赋予1000,然后睡眠,然后③,输入1000,最后再输出b=1000.第二种可能就是先执行③,输入2000,然后再执行①,执行完毕,b =1000,所以总共是这几种情况,但是结果只有2个
    你需要注意的是,①会和②交替使用系统分配的时间片,但是③不会。慢慢领悟吧,语言可能有不周 他说如果是立即启动,b=1000,然后睡眠5000个毫秒,这个时候执行3,为什么会执行3呢?tt.m2()不会被执行吗? 是不是虽然睡眠了5000毫秒,但是主线程依然不能再这个时候调用 m2()方法就是因为 m2()方法是synchronized?
      

  4.   

    http://download.csdn.net/download/xuwenbin2008/3416151
    建议楼主把这张图,下载下来,自己再画出来。
    在学习时随时思考以下线程的状态,或许对你理解有所帮助。
      

  5.   


    public void m2(){
    Thread.sleep(1000);
    b=2000;
    try{
    Thread.sleep(2500);
    }catch(Exception e){
    e.printStackTrace();
    }
    }
      

  6.   

    如果m2 sync之后给你解释一下
    main执行到tt.start()时,有两种可能,一种是立即启动,一种是准备好,就绪状态,暂时不启动。
    启动事实也有可能是在tt.m2()之后启动,因为tt.m2()是主线程的一部分,不好说谁先启动的,这个跟代码前后没太大关系的,(你可以设置优先级或者让两代码之间加点废话,这另说)关键就看谁先启动了,只要有一个启动的,就会锁住当前对象TT,另外一个线程的另外一个方法的运行也需要锁对象,但是已经被提前锁了,所以只能等当前线程执行完在执行。结果就有很多种了
    1:tt.start();  tt.m2(); 这样的结果是
    b=1000
    20002:tt.m2();  tt.start(); 主程序输出;
    结果b=1000
    10003:tt.m2(); 主程序的输出; tt.start;
    结果
    2000
    b=1000