public class TT implements Runnable {
int b = 100;

public synchronized void m1() {
b = 1000;
System.out.println("b = " + b);
}

public synchronized void m2() throws Exception {
Thread.sleep(1000);
b = 2000;
}

public void run() {
m1();
}

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

tt.m2();
System.out.println(tt.b);
}
}
为什么打印出来的是:  1000
                     b=1000  ?????

解决方案 »

  1.   

    如果用DeBug模式结果:2000
    b = 1000
    它是先运行m2方法把b=2000带到main方法中打印b,接着在运行run方法到m1方法中。正常运行模式的结果是:1000
               b=1000
    它是先运行m2后直接运行run方法接着到m1方法中在到main方法把b打印出来b=1000;
      

  2.   

    關鍵是同步了(monitor是TT的實例),所以方法內的等待時間沒派上你原本設想的用途
    一旦先進入m2,另一個線程就會等待m2方法執行完畢后才會進入m1,而且先啟動m2的可能性還偏大(可能主線程的關係,雖然在後面一句)
      

  3.   

    线程同步问题 当程序执行到tt.m2 因为线程睡眠了1秒 所以执行run方法 打印出b=1000 b赋值为1000
    所有在main中打印出1000程序也有可能先执行b=2000 main中打印出2000 之后再执行run方法打印出b=1000
      

  4.   

    有谁知道用webService java类调用XML的配置吗?我用的框架是ssh,要把数据保存到数据库。在此谢谢了。可以发我QQ1132339161
      

  5.   

    结果是不确定的,我这还b = 1000 1000呢。
    原因是m1、m2都是sychronized方法,同一个时刻,只允许一个线程访问一个对象中的一个sychronized方法(例如有线程访问m1的时候,其他线程请求访问该对象的m2也不行)。那么输出的结果就跟线程的推进顺序有关了,主线程时间片没有结束,执行到tt.m2(),此时新建的线程就算执行到run()中访问m1,也会等待主线程执行完了m2,才能够执行m1,结果这两步完了后b还是等于1000.而后是1000 b=1000或者2000 b=1000还是b=1000 1000跟线程的推进执行println的顺序有关,两种结果都是可能的。另一种可能的结果是子线程推进比主线程快,执行到了run中的m1,则会阻塞主线程访问m2,子线程执行完m1后主线程才能访问m2,这时候只有b=1000 2000这种结果。总而言之有1000 b=1000, 2000 b=1000, b=1000 1000,b=1000 2000四种结果。
      

  6.   

    /**
     * CSDN-Thread Synchronized<br>
     * 1、注意synchronized的概念<br>
     * 1.1、synchronized引入了token概念,要执行methodA\methodB就必须先获得token<br>
     * 1.1、同一时间点要么methodA获得token要么methodB获得token<br>
     * 2、注意线程的生命周期,Thread.start()并不代表立刻就能得到CPU时间<br>
     * 3、这段代码的本质的问题应该是验证标记上synchronized方法的互斥执行
     * @version 2012-2-25
     */
    public class ThreadSyncA implements Runnable {
        /** 标记变量 */
        private int bFlag = 100;    /**
         * methodA
         */
        private synchronized void methodA() {
            bFlag = 1000;
            System.out.println("MethodA==>" + bFlag);
        }    /**
         * methodB<br>
         * 1、当前线程先sleep
         */
        public synchronized void methodB() {
            try {
                //即便是线程sleep很长的时间,在没有执行完此方法之前methodA始终没有机会
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            bFlag = 2000;
            System.out.println("MethodB==>" + bFlag);
        }    /**
         * {@inheritDoc}
         */
        public void run() {
            while (true) {
                methodA();
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }    /**
         * 测试入口
         * @param args 参数列表
         */
        public static void main(String[] args) {
            ThreadSyncA tsInst = new ThreadSyncA();
            Thread threadInst = new Thread(tsInst);
            threadInst.start();
            //模拟一下等待,确认让methodA早于methodB调用
            /*try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            tsInst.methodB();
        }
    }