我这里是《Java编程 第二版》,候捷翻译的。
在第14章多线程中629页有这样一段话:
“stop()不被赞同的理由是,它不释放线程所取得的机锁(lock)”可是我经过反复测试,发现stop()是释放机锁的。也就是说,如果线程运行至一个synchronized块时调用stop(),那么该线程会自动释放synchronized块的对象锁。jdk文档中是这么说的:
为什么不鼓励使用 Thread.stop?
因为它本质上就是不安全的。停止线程会导致解锁它已锁定的所有监视程序(ThreadDeath 异常传播到栈上后即解锁监视程序)。如果这些监视程序前面保护的任何对象处于不一致状态,则其它线程即可能将这些对象视为处于不一致状态。我们将这种对象称为损坏的对象。当线程操作损坏的对象时,可能会产生任何意外的行为。这种行为可能很难觉察,也可能非常明显。与其它未检查的异常不同,ThreadDeath 将悄悄杀掉线程;这样,用户就不会得到其程序已被破坏的警告。这种破坏可能会在实际损坏发生之后的任何时间显示出来,甚至可能会在数小时或数天之后。 我对以上说法的理解是:如果调用stop()时,线程执行到一个synchronized块中,那么该块中对需要同步的对象数据的处理将中断,并且释放该对象锁。那么其它线程将可以获得这个对象锁并使用,这样一来,其它线程极有可能获得数据不完整的对象。这可能会造成一些意想不到的后果。 比如:
synchronized(testObj) {
    testObj.a=0;
    testObj.b=0;
    //此时执行了该线程的stop()
    testObj.a=3;
    testObj.b=4;
}
这样,其它线程得到的testObj.a和testObj.b将与所期望得到的值不同。我现在郁闷的是究竟Java编程思想的作者写错了,还是候捷翻译错了?~

解决方案 »

  1.   

    我对以上说法的理解是:如果调用stop()时,线程执行到一个synchronized块中,那么该块中对需要同步的对象数据的处理将中断,并且释放该对象锁。那么其它线程将可以获得这个对象锁并使用,这样一来,其它线程极有可能获得数据不完整的对象。这可能会造成一些意想不到的后果。 比如:
    synchronized(testObj) {
        testObj.a=0;
        testObj.b=0;
        //此时执行了该线程的stop()
        testObj.a=3;
        testObj.b=4;
    }
    这样,其它线程得到的testObj.a和testObj.b将与所期望得到的值不同。
    =============================================================
    个人觉得楼主理解是正确的。
    现在线程中,stop方法已经不提倡使用了。
      

  2.   

    The reason that the stop( ) method is deprecated is because it doesn’t release the locks that the thread has acquired, and if the objects are in an inconsistent state (“damaged”) other threads can view and modify them in that state. The resulting problems can be subtle and difficult to detect.上面是第二版的原文,它说stop不释放线程已获得的锁,这和API doc里的说法以及其它文档中的说法都是冲突的。在一个线程上调用stop,该线程会抛出一个ThreadDeath异常(一个Error),该异常在调用栈(stack)上移,并且在上移过程中,会释放该线程已经获得的所有的锁。可以看出,虽然调用stop也能使得线程占用的所有的锁最终都被释放,但它是破坏性的,无法保证完整性。使用synchronized的初衷就是希望对共享数据的访问能够被保护起来,synchronized块中的操作应该视为原子性的,如果在这个块的中途放弃锁,其它等待锁的线程就可以获得锁而进入同步块,但前一线程对共享数据的修改尚未完全完成,所以数据是脏的。正如楼主举的例子,在线程未完成同步块中的全部操作之前,它的锁就被释放了。如果我们能在希望线程结束的时候,通过某种方式使线程自行结束同步块的执行,就可以避免这些问题。正因为如此,Java deprecate了stop方法,而极力建议用条件判断的方式使线程的run方法自行退出,这样的退出是完整而优雅的,不会留下脏数据。
      

  3.   

    “stop()不被赞同的理由是,它不释放线程所取得的机锁(lock)”针对旧版的jdk吧
      

  4.   

    给作者写了封信,等等看会不会回复,呵呵。Subject: About a word in Thinking in JavaHi Bruce,
     
    I know I'm at risk of having my e-mail sinking to the bottom of your piles of e-mails, anyway, hope it can attract a bit of your attention.
     
    There is such statement about the stop() method for the Thread class in Thinking in Java. It's about the same for 2nd and 3rd editions.
     
    The reason that the stop( ) method is deprecated is because it doesn’t release the locks that the thread has acquired, and if the objects are in an inconsistent state (“damaged”), other threads can view and modify them in that state. 
     
    I don't think you are telling the true story. Let me put my opinions simply.
     
    Invoking stop method within a synchronized block will make a ThreadDeath to be thrown, and when this Error is propagated upward the calling stack, all locks owned by the thread will be released. The bad thing is that the locks are released before all things in the synchronized block get finished while they are supposed to do. Thus shared data may get dirty and visible to other waiting threads. If the locks hadn't been released by the thread on which the stop method is invoked, the underlying object will not become visible to other threads.
     
    Please let me know if I'm wrong somewhere. Looking for your answer.
     
    Thanks.
      

  5.   

    楼上的好文笔。 佩服 & 崇拜
      

  6.   

    CSDN就是牛人多!佩服,佩服,学习,学习!