public void run() {
for (int i = 0; i < 3; i++) {
synchronized (this) {
this.fix(30);
try {
Thread.sleep(1);
} catch (final InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ ":当前对象foo的x值=" + x);
}
}
}

解决方案 »

  1.   

    我试过一下,发现将synchronized 放在整个方法前,是没有问题的。
    楼主的问题我也挺好奇的,感觉是synchronized 没起作用似的,等高手回答
      

  2.   

    是啊,最近在看Java多线程,好迷惑啊!
      

  3.   

    synchronized起作用了,你可以这样跟一个下代码就明白了: ta.start();ta先开启线程,然后执行synchronized里面的代码,遇到Thread.sleep(1);ta睡眠了,可是没有释放执行权,tb是不可能执行的,这时ta继续执行,执行完synchronized里面的代码,这时突然tb抢到执行权了,tb执行,这时x=70;tb执行完synchronized里面的代码后,ta抢到执行权,这时x=40;ta执行打印语句,x=40,执行完tb获取执行权又一次打印x=40;这时就会出现打印两次x=40的情况,接着tb继续执行,打印语句会出现x=10的情况,然后ta执行,打印语句前被tb获取执行权,这时x=-50,打印x=-50,这时tb三次执行完了,后面的就好解释了。
      

  4.   


    不知道这几位朋友在疑问什么?
    当Thread-A到16行时,Thread-B同样可以执行到8行。x先被减30还先被打出没准,出现这个结果很正常。
      

  5.   

    System.out.println(Thread.currentThread().getName()
                    + ":当前对象foo的x值=" + x);这个比较耗时,当A执行完synchronized中的代码x=70,
    开始要syso时,
    B线程过来修改了x的值x=40
    然后也开始syso,A syso出40,B也syso出40我想应该是这样- -
      

  6.   

    我就说你的第一个和第二个的情况吧,当第一个进程进来后,执行函数操作后,为70,正准备要打印,这是Cpu把线程切换到了第二个上,第二个线程进来,继续进行函数操作后,运算后为40,此时有切换到第一个打印出来的肯定是40,在切换到第二个上,打印出来也是40,所以说下面的相同数值肯定也会出现的
      

  7.   

    这位同学已经给出答案了,请把输出语句也锁住呀,不然输出语句执行之前被打断,再受到调度后打印出来的已经不是原来的值了。顶一个,当什么时候synchronized的块结束,这个锁就释放了,所以把system.out.println("xxxx")放入synchronized的块中,给执行完了,才释放锁