`
chinadeng
  • 浏览: 17736 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

java 线程 终止 详细 解释 (interrupt()与中断标志)

阅读更多

 以下下内容均来自网络,只是整理一下;:)

曾经在http://www.iteye.com/topic/1116679,回帖很多,前段时间一直比较忙,没整理。。。;

1) 介绍一下java线程一共有几个状态;

 此图来之core java

  顺便说下,new一个线程出来后,调用start 方法才是处于runnable ,而不是的run()方法线;

  值得注意的是: 线程的可运行状态并不代表线程一定在运行(runnable != running ) 。 大家都知道:所有现代桌面和服务器操作系统都使用了抢占式的线程调度策略 。一旦线程开始执行,并不是总是保持持续运行状态的。当系统分给它的时间片(非常小的运行时间单位)用完以后,不管程序有没有执行完,线程被强制放弃CPU,进入就绪状态,直到下次被调度后开始继续执行。也就是说, Runnable可运行状态的线程处于两种可能的情况下:(1)占用CPU运行中,(2)等待调度的就绪状态。 这里要声明一下:处于等待调度的就绪状态线程和处于阻塞的线程是完全不同的。就绪的线程是因为时间片用完而放弃CPU,其随时都有可能再次获得CPU而运行,这一切取决于分时OS的线程调度策略。(http://hxraid.iteye.com/blog/429005

 2)一下内容参考了http://fujohnwang.github.com/statics/52jump/TerminateJavaThreadGracefully.html

    文中提到比较和谐的结束一个线程 代码如下

1.继承thread类

 

public class GracefulTerminationSupportThread extends Thread {

    protected volatile boolean running = true;

    @Override
    public void run() {
        while (running) {
            // do something as per specific situations
        }
    }

    public void terminate() {
        running = false;
        interrupt();
    }

    public static void main(String[] args) {
        GracefulTerminationSupportThread t = new GracefulTerminationSupportThread();
        t.start();
        // do other things
        t.terminate();
    }
}
2 实现runnable 写法

 

 

public class TerminalSignalSupportRunnable implements Runnable {

    protected volatile boolean running = true;
    
    public void run(){
    	while(running){
    		...
    	}
    }

    public void terminate(Thread threadHandle) {
        running = false;
        threadHandle.interrupt();
    }
}
	
若把terminate 方法里的 threadHandle.interput()换成如下代码,则不会正常终止,为啥会这样,请见作者博文

 

 

Thread.currentThread().interrupt();
3)线程中断 —— interrupt();

 

api 1.6  对中断是这么解释:

Interrupts this thread.

Unless the current thread is interrupting itself, which is always permitted, thecheckAccessmethod of this thread is invoked, which may cause aSecurityException to be thrown.

If this thread is blocked in an invocation of thewait()wait(long), or wait(long, int)methods of the Object class, or of the join()join(long)join(long, int)sleep(long), orsleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive anInterruptedException.

If this thread is blocked in an I/O operation upon aninterruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive aClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector'swakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

Interrupting a thread that is not alive need not have any effect.

1.当线程不是处于api 提出中的三个if 状态,调用 interrupt() 方法,会改变线程的中断标志。

2.当线程处于三个if状态,调用 interrupt() 方法,只把线程提早的结束阻塞状态(处于阻塞状态的线程,没有获得cpu资源),让线程继续运行,他的中断标志不变,

3. 线程结束运行后的,他的中断标志也是false

4.没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断

接下让我们看下如下程序的运行结果:

public class A extends Thread {


public A(){

}
public void run(){
while(!Thread.currentThread().isInterrupted()){
System.out.println("A  在中断前:"+Thread.currentThread().isInterrupted());
/*try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("--A  在中断异常---:"+isInterrupted());
interrupt();
System.out.println("######A  异常后继续中断---:"+isInterrupted());
e.printStackTrace();
}*/
}

}


}

 

public class c {


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub


A aa = new A();
aa.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("***********************C 中判断前"+aa.isInterrupted());
aa.interrupt();// 中断
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(" C 中判断 后isInterrupted()*******************;" + aa.isInterrupted());
}


}

去掉A中的注释,然后在运行

---------------------------------------------------------------------------------------------------------------------------------

以下是一个回帖的内容摘要,这兄弟 ,功底深厚

/* 
* 如果线程被阻塞,它便不能核查共享变量,也就不能停止。这在许多情况下会发生,例如调用
* Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时,他们都可能永
* 久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使
* 用某种机制使得线程更早地退出被阻塞的状态。很不幸运,不存在这样一种机制对所有的情况
* 都适用,但是,根据情况不同却可以使用特定的技术。使用Thread.interrupt()中断线程正
* 如Example1中所描述的,Thread.interrupt()方法不会中断一个正在运行的线程。这一方法
* 实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更
* 确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,
* 它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。因此,
* 如果线程被上述几种方法阻塞,正确的停止线程方式是设置共享变量,并调用interrupt()(注
* 意变量应该先设置)。如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就
* 将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。在任何一种情况中,最
* 后线程都将检查共享变量然后再停止。下面示例描述了该技术。
* */
package Concurrency.Interrupt;

class Example3 extends Thread {

volatile boolean stop = false;

public static void main(String args[]) throws Exception {
Example3 thread = new Example3();

System.out.println("Starting thread...");
thread.start();

Thread.sleep(3000);

System.out.println("Asking thread to stop...");

/*
* 如果线程阻塞,将不会检查此变量,调用interrupt之后,线程就可以尽早的终结被阻 
* 塞状 态,能够检查这一变量。
* */
thread.stop = true;

/*
* 这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退
* 出阻 塞的状态
* */
thread.interrupt();

Thread.sleep(3000);
System.out.println("Stopping application...");
System.exit(0);
}

public void run() {
while (!stop) {
System.out.println("Thread running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// 接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态
System.out.println("Thread interrupted...");
}
}

System.out.println("Thread exiting under request...");
}
}
/*
* 把握几个重点:stop变量、run方法中的sleep()、interrupt()、InterruptedException。串接起
* 来就是这个意思:当我们在run方法中调用sleep(或其他阻塞线程的方法)时,如果线程阻塞的
* 时间过长,比如10s,那在这10s内,线程阻塞,run方法不被执行,但是如果在这10s内,stop被
* 设置成true,表明要终止这个线程,但是,现在线程是阻塞的,它的run方法不能执行,自然也就
* 不能检查stop,所 以线程不能终止,这个时候,我们就可以用interrupt()方法了:我们在
* thread.stop = true;语句后调用thread.interrupt()方法, 该方法将在线程阻塞时抛出一个中断
* 信号,该信号将被catch语句捕获到,一旦捕获到这个信号,线程就提前终结自己的阻塞状态,这
* 样,它就能够 再次运行run 方法了,然后检查到stop = true,while循环就不会再被执行,在执
* 行了while后面的清理工作之后,run方法执行完 毕,线程终止。

* */

在上一篇Ibm社区关于

Dealing with InterruptedException;

分享到:
评论

相关推荐

    interrupt()和线程终止方式_动力节点Java学院整理

    线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以...

    java中终止一个线程的方法总结(精)

     在java中,线程的中断(interrupt)只是改变了线程的中断状态,至于这个中断状态改变后带来的结果,那是无法确定的,有时它更是让停止中的线程继续执行的唯一手段。不但不是让线程停止运行,反而是继续执行线程的...

    Java-并发-Java线程中断与停止线程详解

      Java 中的线程中断是一种线程间的协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是被中断的线程根据中断状态自行处理。即“线程中断”并不是字面意思——线程真的中断了,而是设置了中断标志...

    详解Java多线程编程中线程的启动、中断或终止操作

    在Java中start和tun方法可用被用来启动线程,而用interrupt方法来中断或终止线程,以下我们就来详解Java多线程编程中线程的启动、中断或终止操作

    面试官:如何终止线程?有几种方式?

    使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程终止; 使用 stop() 方法强行终止线程,但是不推荐使用这个方法,因为使用此方法不安全,目前该方法已被弃用; 使用 interrupt()方法中断线程。 第一种...

    java核心知识点整理.pdf

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    Java并发编程实践

    1.3.3 使用中断(Interrupt)取消线程........................................................................15 1.3.4 使用Stop 终止线程........................................................................

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    Java並發編程實踐基礎

    1.3.3 使用中断(Interrupt)取消线程........................................................................15 1.3.4 使用Stop 终止线程........................................................................

Global site tag (gtag.js) - Google Analytics