java线程中断的本质,简单的设计思想(转)

    本文部分内容转自:http://blog.csdn.net/dlite/article/details/4218105,原文作者为:DLite。仅部分摘录。

    一直以来,用过很多线程的应用,最经常使用的就是开启一个线程,然后就不管之,任其运行。或者运行成功,或者运行失败,都跟主线程无关。稍微用得多一点的就是使用对象的wait,再配合线程之间的调度,当线程需要中断时,直接中断其,然后被中断的线程抛出一个中断异常,自然地被中止运行了(因为没有捕获异常,被中断线程方法自然停止运行)。

    但是长久地来看,并没有了解线程中断的实质。从简单上来讲,中断一个线程,可以理解为中断这个线程的运行,就像使用thread.stop方法所运行的一样;并且实际运行效果也是这样,因为线程抛出了异常,而我们没捕获,则线程自然被中断,听起来中断一个线程就和停止线程运行一个效果。但实际上,这是两个完全不一样的工作方式。
    所谓的线程停止,是指这个线程已经不再运行了;而中断,则是指线程由于某种原因被外力(或自身)要求停止不再运行,但线程仍然拥有是否继续运行(或停止运行)的权利,关键在于线程如何处理这个中断的动作。简单一点理解就是,线程中断,只是向线程发送了一个标记,表示这个线程应该中断了,但如何停止运行是由线程自身或处理中断的行为所决定的。
        以下为引用内容:

    JVM内部确实为每个线程维护了一个中断标记。
    通常情况下,调用线程的interrupt方法,并不能立即引发中断,只是设置了JVM内部的中断标记。因此,通过检查中断标记,应用程序可以做一些特殊操作,也可以完全忽略中断。
    你可能想,如果JVM只提供了这种简陋的中断机制,那和应用程序自己定义中断变量并轮询的方法相比,基本也没有什么优势。
    JVM内部中断变量的主要优势,就是对于某些情况,提供了模拟自动“中断陷入”的机制。
    在执行涉及线程调度的阻塞调用时(例如wait、sleep和join),如果发生中断,被阻塞线程会“尽可能快的”抛出InterruptedException。
    所谓“尽可能快”,我猜测JVM就是在线程调度调度的间隙检查中断变量,速度取决于JVM的实现和硬件的性能。

    另外,有jdk源代码为证,下方法为thread的interrupt方法:

    public void interrupt() {
	if (this != Thread.currentThread())
	    checkAccess();

	synchronized (blockerLock) {
	    Interruptible b = blocker;
	    if (b != null) {
//以下此方法,包括调用2,均只设置一个中断标记,下一行的英文注解为原jdk注解
		interrupt0();		// Just to set the interrupt flag
		b.interrupt();
		return;
	    }
	}
	interrupt0();//调用2
    }

    所以,线程中断就是为指定的线程设定一个中断变量,然后当被操作的线程接收到这个变量之后,就努力地抛出一个中断异常出来。由于在一般情况下,我们没有catch这个异常,所以,线程被自然地异常退出了,而且不会影响到主线程。
    在正式地线程调试中,肯定需要对线程的中断行为,定制不同的处理方式,比如安全地释放资源,然后安全的退出等。

继续阅读“java线程中断的本质,简单的设计思想(转)”