为什么总是先打印main to  print

解决方案 »

  1.   

    先执行m1,m1睡眠,回到main中执行m2,m2睡眠,又回到main,所以就先打印main to print
    然后5s过去了,执行m1的print
    把synchronized关键字去掉应该就可以了
      

  2.   

    个人浅见:1 t.start(); 启动这个线程,等待虚拟机进行调度。
    2 主线程执行m2()方法。因为这个方法加了同步(synchronized), 所以要看是否能得到这个锁。在上面第一步,t线程要等待虚拟机调度,所以一般情况下在m2运行时,m1()尚未运行,同步对象锁是空闲的
    3 主线程m2()方法休眠6秒,因为是在同步方法里,所以不释放锁,(m1())因为得不到锁而继续等待。
    4 主线程休眠结束,给b 赋值2000,m2()结束,同步锁释放。
    5 主线程接着执行System.out.println("main to print b="+tt.b);语句。输出main to print b=2000 (但有可能没有执行完,步骤6开始了,那样会输出b=1000. 这块由随机性,并不是总输出1000)。
    6 线程t马上得到同步锁,开始执行b=1000. 然后休眠。
    7 m1 休眠结束,输出m1 of b=1000.楼主想让b = 2000, 只能是 main to print b=2000,可以在m1()方法里,把b=1000;语句放在休眠之后。
      

  3.   

    下面贴代码请使用代码模板。public class Why implements Runnable{
        int b=100;
    public synchronized void m1() throws Exception{
        b=1000;
    Thread.sleep(5000);
    System.out.println("m1 of b="+b);}
    public synchronized void m2() throws Exception{
    Thread.sleep(6000);
    //Thread.sleep(2500);
    b=2000;}
    public void run(){
        try{
        m1();
    }catch(Exception e){
        e.printStackTrace();
    }
    }public static void main(String [] args) throws Exception{
        Why tt=new Why();
    Thread t=new Thread(tt);
    t.start();
    tt.m2();
    System.out.println("main to print b="+tt.b);
    }}
    --------
    main to print=1000;
    m1 of b=1000
    ????
    可以帮我分析执行顺序吗
    这样,别人看的清晰点,也愿意回答。你这个代码是有可能得到2000的,如果你运行足够多次的话。关键在于,第一次拿到锁的是m1方法还是m2方法,如果第一次运行的是m1方法,那有可能输出2000了,你想要的结果。你在里面sleep方法睡多久都没有用,因为你的方法上已经加了内置锁,在你一个方法中睡觉的同时,另外一个方法只能在这个锁上面等待,变成了串行执行。所以,m1m2两方法的顺序,决定了最后的结果。
      

  4.   

    我执行了你的代码,有时候会打印出2000的。这个主意还是多线程的问题。
    1、首先这里有2个线程,1个是主线程,1个是t线程。
    2、如果t线程的m1()方法被先执行,主线程的m2()方法后执行的话,就会打印出2000.
    3、如果主线程的m2()方法先执行,t线程的m1()方法后执行的话,就可能打印出1000.
    4、而且就算主线程的m2()方法执行完,即tt.m2()代码被执行完,cpu也可能立刻唤醒t线程去执行m1()方法,所以还是有可能先执行m1()方法,最后打印System.out.println("main to print b=" + tt.b);这句。
    5、如果你一定要打印出2000的话,就在t.start()后面让主线程等待1秒,这样cpu就会立刻执行t线程,不会出现先执行主线程,后执行t线程的情况了。
    Why tt = new Why();
    Thread t = new Thread(tt);
    t.start();
    Thread.sleep(1000);
    tt.m2();
    System.out.println("main to print b=" + tt.b);
      

  5.   

    m1 sleep 5000
    m2 sleep 6000 //把这里改成1000试试
      

  6.   

    楼上大家说的很好啊。就是主线程休息后怎么调度。mi 和M2 的执行顺序。一个是主线程和一个T1
    线程。