请解释下以下线程的执行顺序,并且告诉我下,为什么的理解是错误的:给出两种执行顺序:
1、
thread.start();进去就绪状态---》调用run()方法,走到m1()--->锁定TT,此时b=1000---》进入休眠5秒状态
在sleep过程中,main方法开始执行,TT由于是锁定状态,则main线程不能调用m2()的方法,只有等待thread线程执行完,5秒过后,thread线程执行完,先打印b=1000 
然后main线程再调用m2()方法,锁定TT,等待2.5秒以后,设置b的值为200,最后打印tt.b的值为2000
最终显示结果为:
b=1000
20002、
thread.start();进去就绪状态---》Main线程执行,调用tt.m2(),TT锁定,m2()方法执行完毕以后才能释放锁,释放锁后thread才能执行m1(),m2休眠2.5秒后,设置b=2000,然后先打印tt.b的值为2000,然后释放锁
然后thread执行m1方法,锁定TT,设置b=1000,等待5秒后,打印b=1000
最终显示结果为:
2000
b=1000
我这边实际的执行结果是
1000
b=10001、请解释这是何种逻辑?
2、假如把m2的synchronized关键字去掉,有是一种啥效果?怎么执行的呢?先谢谢大家!
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{
Thread.sleep(2500);
b=2000;
} @Override
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args)throws Exception {
TT tt = new TT();
Thread thread = new Thread(tt);
thread.start();

tt.m2();
System.out.println(tt.b);
}}

解决方案 »

  1.   

    程序由主线程调用,当执行到thread.start()后,创建了一个新的的线程,去执行m1()方法
    而主线程继续执行,这个时候m2()方法已经调用了。2.5秒后,这个时候m2()方法执行完毕了,
    而m1()方法还没完毕,因此此时的时候b仍然等于1000.所以会先输出1000,然后输出b=1000.这个跟synchronized没关系吧,没有多个线程同时访问同一个方法啊??
    如果不清楚的话,可以把m2()方法里面的暂停去掉,这样的话就是LZ猜测的第二种结果了。
      

  2.   

    以下仅代表个人观点:
        主线程启动了两个线程,由main线程生成了一个thread线程,两个线程虽然没有什么关联关系,但是新线程的启动肯定需要时间,虽然时间很短但是没有main线程直接继续运行来的快,所以是main线程优先进入了m2方法,由于m2方法是synchronized方法,即使thread线程初始化完成了,也要等待锁释放,等main线程的tt.m2();执行完成后,thread线程才可以执行。这时两个线程就并发执行了,如果thread执行的快,就会输出“1000”,否则,就会输出“2000”。但是由于thread线程因为等待了5秒,最后输出的肯定是“b=1000”。
       不知道说的清不清楚?
      

  3.   

    其实就一句话:线程同步问题!
        两个线程要是不进行同步,其中指令的执行顺序是不可预期的!
        也就是说:结果可能与你预期相同,也可能不同,同或不同,都属于概率事件!具体而言:你这里用的synchronized关键字,只保证了两个方法不会同时执行,但却无法保证二者到底谁先执行!从设计者的角度而言,如果两个事件需要顺序发生,那么一般不会将其分派到两个不同线程中执行!否则,需要的同步机制是比较复杂的。
      

  4.   

    按照我的逻辑来讲,我觉得这三种结果都有可能
    1、
    b=1000
    2000
    2、
    2000
    b=1000
    3、
    1000
    b=1000
    但是经过多次测试,没有出现第一种结果。得到1000,b=1000的原因就是当tt.m2()执行后,由于cpu速度快,thread线程执行,先设置了b=1000,然后休眠5秒,此时main线程进行打印tt.b的值,则是1000.
    如果cpu运行的慢点,先打印了tt.b,然后才轮到thread线程,则结果是2000,b=1000(cn_gaowei的说法是对的)但是我纳闷的是,第一种结果杂就没有呢? 先打印b=1000,然后再打印2000,是不是我的想法本身就是错误的呢?当两个线程执行的时候,一般怎么去判断他先执行哪个后执行哪个呢?
      

  5.   

    如果楼主想按顺序来执行的话,可以在run()里面加上m1();m2();或是m2();m1();像楼主上面的代码那么执行的话,执行结果确实是不可预计的
      

  6.   


    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{ Thread.sleep(2500); b=2000; } @Override public void run() { try { m1(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args)throws Exception { TT tt = new TT(); Thread thread = new Thread(tt); thread.start(); tt.m2(); System.out.println(tt.b); } } 楼主你代码的结果是随机的
      

  7.   

    main方法开始执行,TT由于是锁定状态TT并没有加锁,加锁的只是那2个方法所以main不会等待而是直接执行,如果要将整个实例锁住需要对整个对象加锁
      

  8.   


    public class Test {
    public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 50; i++) {
    T t = new T();
    Thread tt = new Thread(t);
    tt.start();
    t.m2();/*永远先打印m2  因为  tt.start()创建线程需要分配资源等操作,需要耗时,而t.m2()是顺序执行下来的,所以先执行此方法,会锁住t对象实例,线程tt虽然已经启动但任续等待t.m2()方法释放锁。呵呵楼主多看下多线程方面的书再多做点练习就熟了*/
    } }
    }class T implements Runnable { public void m1() throws InterruptedException {
    synchronized (this) {
    // Thread.sleep(2500);
    System.out.println("i'm m1");
    }
    } public void m2() throws InterruptedException {
    synchronized (this) {
    // Thread.sleep(5000);
    System.out.println("i'm m2");
    }
    } public void run() {
    try {
    m1();
    } catch (Exception e) {
    }
    }
    }
      

  9.   

    以下仅是个人理解,如有错误请指出:
    在这个程序中,程序启动两个线程,一个是main线程,另一个是在main中启动的线程thread.start();,由于这个线程中使用synchronized管住了m1()方法,但注意管理住的只是m1()方法,只能说明这个thread对象在使用的这个方法的时候是互斥使用这个方法,但并不互斥使用m1()方法中的变量,所以在tt.m2();改变了b之后,有可能还是main线程在运行,这时就打印的是2000,如果在tt.m2()改变b之后,由于线程切换,有可能是由thread.start()方法启动的线程在执行,这时这个线程又执行了一次b的赋值,这时两个线程打印的结果都是1000;
      

  10.   

    你就能确定先运行main里面的???