`
chinadeng
  • 浏览: 18118 次
  • 性别: 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;

分享到:
评论

相关推荐

    java线程中断之interrupt和stop.docx

    ### Java线程中断机制详解:`interrupt`与`stop`方法 #### 一、引言 在Java多线程编程中,线程控制是至关重要的技术之一。有时我们需要在特定条件下停止某个线程的执行,或者中断正在等待的线程。Java提供了多种...

    java中 如何终止一个线程

    本篇文章将详细探讨如何使用`interrupt()`方法安全地终止一个线程。 #### 一、为什么不能强制停止线程? 在Java早期版本中,提供了`Thread.stop()`方法来直接终止线程,但这种方法存在严重的安全问题。例如,它...

    深入分析JAVA 多线程--interrupt()和线程终止方式

    JAVA 多线程 interrupt() 和线程终止方式 JAVA 多线程中,interrupt() 和线程终止方式是两个非常重要的概念。本文将深入分析 JAVA 多线程中 interrupt() 和线程终止方式的相关知识。 一、interrupt() 介绍 ...

    Java线程如何终止.pdf

    以下将详细解释三种主要的Java线程终止方法。 1. **使用退出标志终止线程** 当一个线程的`run`方法执行完毕时,线程会自动终止。然而,有些线程可能包含无限循环,例如服务器监听客户端请求的线程。在这种情况下,...

    java线程与并发编程实践

    本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,提供了关于Java线程API和并发工具的详细指南,帮助开发者深入理解和应用这些关键概念。 首先,Java线程是程序执行的独立路径,每个线程都有自己...

    java线程详细资料

    - **interrupt()**:中断线程,注意它不会立即停止线程,而是设置一个中断标志。 - **isInterrupted(), interrupted()**:检查线程是否被中断。 6. **线程池** - **ExecutorService**:Java提供的线程池接口,...

    java线程实例 各种小Demo

    Java线程有五种状态:新建、可运行、运行、阻塞和终止。可以通过Thread类的getState()方法查看线程状态。线程的控制包括: - sleep():使当前线程进入休眠状态,指定时间后自动唤醒。 - join():让当前线程等待另一...

    Java 实例 - 中断线程源代码+详细指导教程.zip

    10. **中断与守护线程**:守护线程(Daemon Thread)通常用于后台服务,Java虚拟机在所有非守护线程结束后才会退出。中断守护线程同样需要遵循上述原则,确保它们能正确响应中断。 通过本压缩包中的源代码实例和...

    Java线程.ppt

    Java线程是Java编程中的重要概念,特别是在多核处理器和并发处理中不可或缺。Java线程允许程序在同一时间执行多个不同的任务,从而提高了程序的效率和响应性。在燕山大学信息学院计算机系的课程中,李峰教授讲解了...

    java线程实战手册

    6. **线程中断与停止**:正确地停止线程是一项挑战,Java提供了interrupt()方法来请求线程中断,但需要注意的是,这并不一定能立即停止线程,需要配合中断标志进行检查和处理。 7. **线程池**:Executor框架和...

    java线程.rar

    9. **线程中断**:通过`interrupt()`方法设置线程的中断标志,线程可以通过检查`isInterrupted()`或`interrupted()`方法来响应中断请求。 10. **线程Local变量**:`ThreadLocal`类为每个线程提供独立的变量副本,...

    JAVA线程学习(源代码)

    Java提供了多种方法来控制线程状态,如`start()`启动线程,`sleep()`使线程暂停,`join()`等待线程完成,以及`interrupt()`中断线程。 并发控制是线程编程中的重要部分。Java提供了synchronized关键字来实现互斥...

    Java多线程机制(讲述java里面与多线程有关的函数)

    挂起线程通常通过调用`sleep()`或`wait()`方法实现,恢复线程可能通过`notify()`或`notifyAll()`唤醒,终止线程则可以通过`interrupt()`方法发送中断请求,但线程本身需要检查`isInterrupted()`或`...

    java多线程详细讲解

    本文将深入探讨Java多线程的详细知识,包括线程的创建、同步与通信、线程状态以及相关API的使用。 1. **线程的创建** - **实现Runnable接口**:这是创建线程的常见方式,通过实现Runnable接口并重写run()方法,...

    Java多线程之中断线程(Interrupt)的使用详解

    `Thread.interrupt()`方法是中断线程的主要手段,但它的行为并不像字面意义上那样直接终止线程。相反,它通过设置线程的中断状态来向线程发送一个中断信号,这个信号是一个内部标志,告知线程应该停止其当前的工作。...

    电子书《java线程》

    8. **中断与异常**:线程可以通过interrupt()方法发送中断信号,以及如何处理InterruptedException。 9. **守护线程(Daemon)**:守护线程不会阻止程序退出,常用于后台服务。 10. **线程本地存储(ThreadLocal)...

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

    在Java多线程编程中,终止一个线程并非像许多人所理解的那样简单直接。线程的"中断"并不是让线程立即停止执行,而是一个标志,用来指示线程应该中断其当前活动并采取相应措施。Java提供了多种方法来处理线程的中断,...

    JAVA线程停止的方法

    本文将深入探讨Java线程停止的方法,特别是通过一个示例代码片段来解析如何利用标志变量(Flag)控制线程的生命周期,以及这种方法背后的原理与最佳实践。 ### Java线程停止方法概述 在Java中,直接调用线程的`...

Global site tag (gtag.js) - Google Analytics