看下面的程序:
public class TT implements Runnable{
int b = 100;

public synchronized void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
}

public synchronized void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
}

public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
}

public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();

tt.m2();
System.out.println(tt.b);
}
}假如没有把注释的东西注释掉,结果又是如何?还有结果是不是唯一?

解决方案 »

  1.   

    楼主请看:
    http://topic.csdn.net/u/20090421/22/16f06a01-9688-4dc8-9352-62c82c6adfb5.html
      

  2.   

    代码没有贴好,重新贴下:public class TT implements Runnable{ 
    int b = 100; public synchronized void m1() throws Exception{ 
    //System.out.println("m1 start..."); 
    b = 1000; 
    Thread.sleep(5000); 
    System.out.println("b = " + b); 
    //System.out.println("m1 end..."); 
    } public synchronized void m2() throws InterruptedException{ 
    //System.out.println("m2 start..."); 
    Thread.sleep(2000); 
    b = 2500; 
    //System.out.println("m2 end..."); 
    } public void run() { 
    //System.out.println("run start..."); 
    try{ 
    m1(); 
    }catch(Exception e){ 
    e.printStackTrace(); 

    //System.out.println("run end..."); 
    } public static void main(String[] args) throws InterruptedException { 
    TT tt = new TT(); 
    Thread t = new Thread(tt); 
    t.start(); tt.m2(); 
    System.out.println(tt.b); 


    假如没有把注释的东西注释掉,结果又是如何?还有结果是不是唯一?
      

  3.   

    代码还是不好看,帮忙重新贴一下
    public class TT implements Runnable{ 
    int b = 100;  public void m1() throws Exception{ 
    //System.out.println("m1 start..."); 
    b = 1000; 
    Thread.sleep(5000); 
    System.out.println("b = " + b); 
    //System.out.println("m1 end..."); 
    }  public void m2() throws InterruptedException{ 
    //System.out.println("m2 start..."); 
    Thread.sleep(2000); 
    b = 2500; 
    //System.out.println("m2 end..."); 
    }  public void run() { 
    //System.out.println("run start..."); 
    try{ 
    m1(); 
    }catch(Exception e){ 
    e.printStackTrace(); 

    //System.out.println("run end..."); 
    }  public static void main(String[] args) throws InterruptedException { 
    TT tt = new TT(); 
    Thread t = new Thread(tt); 
    t.start();  tt.m2(); 
    System.out.println(tt.b); 

      

  4.   

    m2 start...     run start...
    run start...     m2 start... 

    m1 start...     m1 start...
    m2 end...      m2 end...
    2500          2500
    b = 2500     b = 2500
    m1 end...    m1 end...
    run end...    run end...
        我觉得只可能出上面两种结果
      

  5.   


    D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac TT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java TT
    2500
    b = 2500D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac ATT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java ATT
    2500
    b = 2500D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac ATT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java TT
    2500
    b = 2500
      

  6.   

    m2 start...
    run start...
    m1 start...
    m2 end...
    2500
    b = 2500
    m1 end...
    run end...
      

  7.   

    带注释的情况,只能输出:
    b = 2500
    一种情况,
    因为无论线程以什么顺序执行,m2 sleep的时间远低于m1的sleep时间,
    所以等线程苏醒的时候,m2肯定已经被执行了,b总是2500.
    但如果去掉注释,那么
    最后
    b = 2500
    这个结果不会变,
    但其它调试信息的顺序,会有好多种可能性:
    不少于4种。
      

  8.   

    执行结果:m2 start...
         run start...
         m1 start...
         m2 end...
         2500
         b = 2500
         m1 end...
         run end...
    多线程,并不是指多个线程在同一个时间同时运行。它只是利用操作系统的时间片轮转的功能。
    先运行这个线程几秒,然后停在,再去运行另一个线程。只是时间分的很快,让我们感觉到这
    几个线程是同时运行的。
         当程序运行时,执行的是main这个线程。当开启t这个新线程的时候,main这个线程的时间片
    还没有完成,所以它接着执行。当它sleep的时候,t 的新线程得到了运行的机会这时b=1000.接着
    2秒过去了,main又得到了运行机会,将b设成2500,然后打印输出System.out.println(tt.b)。这时
    main的线程结束了。之后t接着运行,直到结束。
      

  9.   


    对于你说的第一种情况:     你是如何确保子线程中的m1()方法中的语句:b = 1000; 这条语句是在是m2()执行完后再执行还是在先执行这条语句再执行方法m2()的。对于你说的第二种情况:     你没有自己运行程序看一下吗?
      

  10.   

    对于你说的第一种情况:     你是如何确保子线程中的m1()方法中的语句:b = 1000; 这条语句是在是m2()执行完后再执行还是在先执行这条语句再执行方法m2()的。 
    依据在于:无论怎样,两个方法的sleep有3秒钟差距,CPU在三秒之内不执行不到b=1000的可能性,可以说为0.对于你说的第二种情况:     你没有自己运行程序看一下吗? 多线程的各种调度情况,执行一两次不可能得到所有结果,多数是相同的结果。
    但只要执行的次数足够多,一定会出现不一样的调度顺序。所以,只是做理论验证而已。
      

  11.   

    两个方法的sleep有3秒钟差距,CPU在三秒之内不执行不到b=1000的可能性,可以说为0. 
    我认为这句话是理论性的,虽然可能性小,但是是有可能的
      

  12.   

    是不是我看错了,我怎么觉得3楼的代码和2楼的不一样了?把synchronized关键字给去掉了?
      

  13.   


    厉害啊!!!!!!!如果有了synchronized,那么结果就大大不同了。
      

  14.   


    public class TT implements Runnable {
    int b = 100; public synchronized void m1() throws Exception {
    // System.out.println("m1 start...");
    b = 1000;
    Thread.sleep(5000);
    System.out.println("b = " + b);
    // System.out.println("m1 end...");
    } public synchronized void m2() throws InterruptedException {
    // System.out.println("m2 start...");
    Thread.sleep(2000);
    b = 2500;
    // System.out.println("m2 end...");
    } public void run() {
    // System.out.println("run start...");
    try {
    m1();
    } catch (Exception e) {
    e.printStackTrace();
    }
    // System.out.println("run end...");
    } public static void main(String[] args) throws InterruptedException {
    TT tt = new TT();
    Thread t = new Thread(tt);
    t.start(); tt.m2();
    System.out.println(tt.b);
    }
    }运行结果:
    1000
    b = 1000在也没有其他的输出了
      

  15.   


    2500
    b = 1000
    或者
    1000 
    b = 1000 synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)
      

  16.   

    晕,三楼把我程序改变了一下,我没有仔细看,不好意思啊,方法m1(),m2(),前面都有synchronized来声明,大家应该看看二楼,三楼改错了。
      

  17.   

    如果是这样,理论上来讲有两种结果。
    要么M1先执行完,再执行M2,
    或者反过来。但实际上,由于m2在主线程中,通常会比新的线程更容易抢占CPU,
    所以出b=1000的概率大的多。
      

  18.   

    public static void main(String[] args) throws InterruptedException {
    TT tt = new TT();
    Thread t = new Thread(tt);
    t.start();tt.m2(); //调用的是TT方法不是run
    System.out.println(tt.b);
    }

    在执行System.out.println(tt.b);后
    t.start 还没执行完
    打印出的就是int b = 100;等t.start() 结束后
    main线程才结束()可以在tt.m2(); 后添加让主线程sleep更长时间
    在看看结果....
      

  19.   


    执行System.out.println(tt.b);
    t.start还没有执行完,这个我赞成,但是它执行到那了?为什么大部分都是在执行了        Thread.sleep(2000);
            b = 2500;后再执行        b = 1000;
    我相信大家得到的结果基本上都是:
    1000
    b = 1000
      

  20.   

    同25楼, 这个没有定数, 谁先sleep和谁sleep时间长这里并不决定CPU执行谁.只是CPU不可能总闲着. 
      

  21.   

    21搂的,这样的情况只能打印出
    1000 
    b = 1000 
    不可能有别的结果~我认为运行情况是这样的:
    t.start();    //主线程开始运行tt.m2(); //调用的是TT方法不是run 
    System.out.println(tt.b); 


    但是由于m2()方法的时间短于m1()方法,先是m2()方法调用完,打印了System.out.println(tt.b); 这个值,然后再执行主线程的方法,所以就打印了m1()方法的值。
      

  22.   

    结果很难预料:
    我们可以肯定的main方法中的语句执行顺序如下:
    TT tt = new TT();
    Thread t = new Thread(tt);
    t.start();
    tt.m2();
    System.out.println(tt.b);
    但调用了t.start()方法,并不意味着t线程会立即执行,这只是将t线程加入了等待队列中,
    1、有可能先执行tt.m2()方法,再执行t线程,
    2、也有可能先执行t线程,再执行tt.m2()方法
    但由于又加入了synchronized关键字,就有会使m1和m2方法不会同时执行,但执行的先后顺序很难预料,至于打印的结果更难预料。
      

  23.   


    34楼,先是m2()方法先调用完,打印了System.out.println(tt.b); 结果是多少?是2500吧?为何结果是1000?你没有解释啊..
      

  24.   

    public class TT implements Runnable{ 
        int b = 100;     public void m1() throws Exception{ 
            //System.out.println("m1 start..."); 
            b = 1000; 
            Thread.sleep(5000); 
            System.out.println("b = " + b); 
            //System.out.println("m1 end..."); 
        }     public void m2() throws InterruptedException{ 
            //System.out.println("m2 start..."); 
            Thread.sleep(2000); 
            b = 2500; 
            //System.out.println("m2 end..."); 
        }     public void run() { 
            //System.out.println("run start..."); 
            try{ 
                m1(); 
            }catch(Exception e){ 
                e.printStackTrace(); 
            } 
            //System.out.println("run end..."); 
        }     public static void main(String[] args) throws InterruptedException { 
            TT tt = new TT(); 
            Thread t = new Thread(tt); 
            t.start();         tt.m2(); 
            System.out.println(tt.b); 
        }