线程中断

阅读更多

本文转载自:http://blog.chinaunix.net/uid-122937-id-215995.html

1.中断概述
      在多线程编程中经常会遇到需要中止线程的情况,比如启动多个线程去数据库中搜索,如果有一个线程返回了结果,其他线程就可以取消了。

中断线程的三个相差函数
            1.通过成员方法Thread.interrupt()来设置中断状态为true
            2.通过成员方法Thread.isInterrupted()来获取中断状态
            3.通过静态方法Thread.interrupted()来获取中断状态,并且清除中断状态(当然获取的是清除之前的值),也就是说连续两次调用此方法,第二次一定会返回false。

对正在运行的线程调用
interrupt(),并不会使线程停止运行,而只是让线程暂停一会,详见《例1:中断但不停止线程的运行》。因为Thread.interrupt() 对正在运行的线程是不起作用的,只有对阻塞的线程有效

离开线程有三种常用的方法:
1.在阻塞操作时如Thread.sleep()时被中断会抛出InterruptedException
       Thread.interrupt()方法实际上只是设置了一个中断状态,当该线程由于下列原因而受阻时,这个中断状态就起作用了:
      (1)如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException异常。这个时候,我们可以通过捕获 InterruptedException异常来终止线程的执行,具体可以通过return等退出或改变共享变量的值使其退出。
      详见《例2:线程在sleep时调用interrupt

      (2)如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException,而不是InterruptedException 异常。
     
      (3)如果使用Java1.0之前就存在的传统的I/O操作,并且线程处于阻塞状态,Thread.interrupt()将不起作用,线程并不能退出阻塞状态。
               例如对于socket,通过调用阻塞该线程的套接字的close()方法。如果线程被I/O操作阻塞,该线程将接收到一个SocketException异常,这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似。
      详见《例6:通过SocketException异常中断阻塞线程

2.Thread.interrupted()检查是否发生中断
      对于正在运行的线程,如果调用thread.interrupt()。可以通过Thread.interrupted()能告诉你线程是否发生中断,并将清除中断状态标记,所以程序不会两次通知你线程发生了中断。
      详见《例3:通过interrupted中断线程

      如果sleep和interrupted检查结合使用,可能会产生两个结果。
      详见《例4: 通过interrupted和sleep中断线程,停止线程的执行

3.使用共享变量控制
      使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务。
      详见《例5:通过共享变量中断线程,停止线程的执行

      这个方法虽然给予线程机会进行必要的清理工作,这在任何一个多线程应用程序中都是绝对需要的。请确认将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法(synchronized blocks/methods)中。

      但是,当线程等待某些事件发生而被阻塞,又会发生什么?当然,如果线程被阻塞,它便不能核查共享变量,也就不能停止。
      他们都可能永久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使用某种机制使得线程更早地退出被阻塞的状态。

总结
      不存在这样一种机制对所有的情况都适用,但是,根据情况不同却可以使用特定的技术。
      详见《java线程技术8_线程中断最佳实践

你可能感兴趣的:(Thread,线程中断,interrupt)