这个就是所谓的synchronized的意义哟!

解决方案 »

  1.   

    同步要求同步代码段必须在获得LOCK的情况下才可以运行,为什么在
    LINE 6    synchronized ( b ) 没有获得b的LOCK的情况下就可以运行其后(line6-10)的代码?
    如果把12行  System.out.println("Total is: " + b.total);
    放到第9行前,运行结果就是
    Waiting for b to complete...
    Total is: 0 
    也就是说同步代码段(line6-10)在根本没有获得lock的情况下就运行了,同步的意义在那里?
      

  2.   

    你说些什么呀?!难道一定是线程b先获得b上的lock吗?
      

  3.   

    呵呵,楼主,你的理解力真够强的!
    synchronized(b)
    和synchronized(this)
    在竞争同一把锁,你能保证那个先竞争到?在你的例子中,应该是synchronized(b)先竞争到锁,然后执行System.out.println("Waiting for b to complete...");,然后b.wait()会释放锁并进入等待区。
    在main线程释放锁之后,synchrinized(this)[线程中的run方法]会得到锁,开始运行,直到执行notify()然后退出monitor(当然也释放了锁)。
    notify之后,等待区中的main线程被唤醒,然后继续执行。
    在这样的流程中,你把L12放到L9,当然是输出0了,run()方法还在入口区等待锁呢,根本就没有执行。Java的线程调度没有错,synchronized没有错,只能说你的理解有错。而且用法有错。
      

  4.   

    在第二种情况之下,同步代码段(line6-10)肯定是首先获得了 b 的 lock 了,否则的话,是肯定不会运行的。但是为什么会出现先打印出:
    Waiting for b to complete...
    Total is: 0 
    呢,这是因为线程的无序性引起的。也就是说线程何时运行、何时停止,你是无法预知的(当然,手动在代码里面控制是可以的。)。也就是说,在运行到b.start(),你可能认为CPU就会马上就去执行b线程的启动工作,然后计算出i的值;这是错的,系统很可能在刚要开始计算i的值的时候,b线程的CPU时间就到了,这个时候,系统会将时间重新再交给ThreadA的main线程(注意:main方法也是一个线程!),所以就会出现了先运行下面的同步区段的情况。这是很正常的。
      

  5.   

    谢谢各位大虾,小弟刚开始学习线程
    刚才的结论基于我的一个误解:线程start以后就拥有lock了,sorry
    不过从我运行这个程序来看
    synchronized(b),synchronized(this)的竞争总是前者获胜,看来main线程还是比较
    牛的说!
    谢谢各位!
      

  6.   

    <<synchronized(b),synchronized(this)的竞争总是前者获胜,看来main线程还是比较牛的说!>>呵呵,你的说法真有意思。和main线程没有关系。在jvm的线程模型中,没有区分这些。都是一视同仁的。除了线程可以有优先级的区别。
    为什么main线程会抢在前面呢?在JVM中,所有的线程共享方法区和堆内存,而每个线程都有自己的JAVA栈和PC寄存器。当创建新线程的时候,会为之分配属于它自己的PC寄存器和一个JAVA栈。(b.start())就是在创建新线程。创建线程是需要开销的,也就是说在开始创建线程和线程创建完成是有一定的时间差的『主要开销就是分配JAVA栈和PC寄存器』。
    在这个时间差,别的线程当然可以运行(比如说你的main线程)。所以给你感觉“main线程比较牛”,呵呵。(main方法是初始线程的起点,任何其他的线程都是由这个初始线程启动的。)
      

  7.   

    仔细看了一下,“sirch(还倾城)”的这段解释是有问题的:
    <<
    系统很可能在刚要开始计算i的值的时候,b线程的CPU时间就到了,这个时候,系统会将时间重新再交给ThreadA的main线程(注意:main方法也是一个线程!)
    >>
    这里不是CPU时间分片的问题,在整个monitor中,能持有同一把锁的只能有一个线程,也就是所说的互斥。而b线程和main线程竞争的同一把锁,任何一个持有锁都会阻塞另外一个线程。直到当前持有锁线程释放锁『两种释放方式:等待和退出』,另外的线程才会持有锁,开始运行。
      

  8.   

    to xiaohaiz(老土进城,两眼通红) 
    还请问高手如果要深入了解java的话,需要看些什么书啊?
    《深入java虚拟机》?
    我对J2EE很感兴趣,但总有一种无从下手的感觉,可不可以给点建议!多谢
      

  9.   

    想深入了解JAVA,俺的建议是首先从 JLS (Java Language Specification) 入手(如果你之前没有看过的话)。《深入JAVA虚拟机》是Bill Venners的书,非常不错,不过据俺的了解,没有几个初哥上来就能看明白的,如果有操作系统的背景对于学习JVM还是非常有帮助的。
      

  10.   

    to xiaohaiz(老土进城,两眼通红)
    多谢!
    还请高手给我点学习J2EE的建议,真的感觉无从下手!