public class TTT implements Runnable {
int b = 100; public static void main(String[] args) throws InterruptedException {
TTT tt = new TTT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
} private synchronized void m2() throws InterruptedException {
System.out.println("m2=" + b);
b = 2000;
} public void run() {
try {
m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void m1() throws InterruptedException {
System.out.println("开始的b=:" + b);
b = 1000;
Thread.sleep(5000);
System.out.println("m1=" + b);
}
}我睡眠了5秒 前面的b=2000为什么改变不了m1的值

解决方案 »

  1.   

    t.start();只是启动新线程,什么时候执行可不知道。“b=2000改变不了m1的值”:这是因为m2先于m1运行了,想要看出另一种效果,lz可以让主线程也睡一会:
    public static void main(String[] args) throws InterruptedException {
    TTT tt = new TTT();
    Thread t = new Thread(tt);
    t.start();
    Thread.sleep(6000);//要睡得比m1长
    tt.m2();
    System.out.println(tt.b);
    }
      

  2.   

    除1楼说的外,另一种更安全的方式,就是主线程等待子线程结束。t.start();
    t.join(); // 等待子线程结束
    tt.m2();
      

  3.   

    因为你同步了啊,就算你让m1等待5秒(假设m1执行的更早一些),在这段时间内,m2也是不会执行的,只有m1执行完了,m2才会执行,这是同步造成的
      

  4.   


    为什么一定要让主线程 比子线程睡的时间要长 当b=2000  子线程正在睡眠 这个时候   b=2000 不会改变b的值么?
      

  5.   

    我是说去掉 m2()方法的同步   也就是这样
    public class TTT implements Runnable {
     int b = 100; public static void main(String[] args) throws InterruptedException {
     TTT tt = new TTT();
     Thread t = new Thread(tt);
     t.start();
     tt.m2();
     System.out.println(tt.b);
     } private void m2() throws InterruptedException {
     System.out.println("m2=" + b);
     b = 2000;
     } public void run() {
     try {
     m1();
     } catch (InterruptedException e) {
     e.printStackTrace();
     }
     } public synchronized void m1() throws InterruptedException {
     System.out.println("开始的b=:" + b);
     b = 1000;
     Thread.sleep(5000);
     System.out.println("m1=" + b);
     }
    }
      那现在的执行过程 又有那些可能啊?
      

  6.   

    “当b=2000 子线程正在睡眠 这个时候 b=2000 不会改变b的值么?”b=2000确实改变了b的值,但是之后又被b=1000这句覆盖了。根据程序运行结果:
    运行m2中的b=2000这句的时候,子线程没有在睡眠,子线程在“阻塞”或者“可运行“状态。“为什么一定要让主线程 比子线程睡的时间要长”这是为了让子线程先于主线程醒过来,也就是让b=1000在前,b=2000在后,这样就能看到最终结果是2000了不知我说明白了没
      

  7.   

    版主,经过测试,线程在调用start()方法的时候并不会立即启动run()方法,系统要准备生产线程等要消耗时间,当然时间很少,所以他会先执行名m2()方法,你在m2方法里面写synchronized其实在你这个程序里面没有什么意义,你可以再增加一个方法比如m3(),主要是你增加了synchronized方法,当运行到m2()的时候,它不会去运行m3()而是等到m2运行完之后再去选择运行run方法还是m3方法,这个要看时间,你可以在方法里面插入System.currentTimeMillis()看看时间快慢,哪个时间短,就运行哪个方法,你用同步的意思再java里面就是说它要完整执行完整个方法体之后才会释放。然后接着执行下一个.
      

  8.   

    楼主可以先说说想达到什么样的效果。
    一般来说,在实例方法前加synchronized会以这个类实例为锁对象,所以任何方法成功调用这个方法,会拥有这个对象的锁,别的线程就只能等待。
    m1和m2两个方法都是synchronized的,可见你想让他们达到互斥的作用。
    按照你的写法,m1和m2没有特定的执行顺序。
      

  9.   

    嗯 理解了很多   这个问题跟执行时间跟顺序 有一定关系   若是先执行子线程 当b=1000  赋值完毕 改变了b的值这个时候 子线程进入睡眠状态  m2()方法里面 b=2000正好执行 然后子线程睡眠完毕  执行打印m1=b的操作  那么最后打印的m1=1000?  还是2000  
      

  10.   

    开始的程序最终的m1肯定是2000,另外主线程的睡眠时间不用睡得比m1长,加个sleep减慢一下程序的执行,线程创建并执行要消耗时间,但主线程会继续往下进行,并执行了m2,获得锁,然后m1只能等m2执行结束才能被调用。建议楼主采用3楼方法,或者主线程加个短时间sleep即可,保证创建的线程能执行。