如何停止JAVA线程

如何停止JAVA线程

如何停止java的线程一直是一个困恼我们开发多线程程序的一个问题。这个问题最终在Java5的java.util.concurrent中得到了回答:使用interrupt(),让线程在run方法中停止。

简介

在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start()stop()stop(Throwable) and suspend()destroy() and resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。

在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲解了舍弃这些方法的原因。那么,我们究竟应该如何停止线程呢?

建议使用的方法

在《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中,建议使用如下的方法来停止线程:

private volatile Thread blinker; 
    public void stop() { 
        blinker = null; 
    } 
    public void run() { 
        Thread thisThread = Thread.currentThread(); 
        while (blinker == thisThread) { 
            try { 
                thisThread.sleep(interval); 
            } catch (InterruptedException e){ 
            } 
            repaint(); 
        } 
    }

关于使用volatile关键字的原因,请查看http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930

当线程处于非运行(Run)状态

当线程处于下面的状况时,属于非运行状态:

  • 当sleep方法被调用。
  • 当wait方法被调用。
  • 当被I/O阻塞,可能是文件或者网络等等。

当线程处于上述的状态时,使用前面介绍的方法就不可用了。这个时候,我们可以使用interrupt()来打破阻塞的情况,如:

public void stop() {        Thread tmpBlinker = blinker;        blinker = null;        if (tmpBlinker != null) {           tmpBlinker.interrupt();        }    }

interrupt()被调用的时候,InterruptedException将被抛出,所以你可以再run方法中捕获这个异常,让线程安全退出:

try {   ....   wait();} catch (InterruptedException iex) {   throw new RuntimeException("Interrupted",iex);}

阻塞的I/O

当线程被I/O阻塞的时候,调用interrupt()的情况是依赖与实际运行的平台的。在Solaris和Linux平台上将会抛出InterruptedIOException的异常,但是Windows上面不会有这种异常。所以,我们处理这种问题不能依靠于平台的实现。如:

package com.cnblogs.gpcuster

import java.net.*;import java.io.*;

public abstract class InterruptibleReader extends Thread {

private Object lock = new Object( );    private InputStream is;    private boolean done;    private int buflen;    protected void processData(byte[] b, int n) { }

class ReaderClass extends Thread {

public void run( ) {            byte[] b = new byte[buflen];

while (!done) {                try {                    int n = is.read(b, 0, buflen);                    processData(b, n);                } catch (IOException ioe) {                    done = true;                }            }

synchronized(lock) {                lock.notify( );            }        }    }

public InterruptibleReader(InputStream is) {        this(is, 512);    }

public InterruptibleReader(InputStream is, int len) {        this.is = is;        buflen = len;    }

public void run( ) {        ReaderClass rc = new ReaderClass( );

synchronized(lock) {            rc.start( );            while (!done) {                try {                    lock.wait( );                } catch (InterruptedException ie) {                    done = true;                    rc.interrupt( );                    try {                        is.close( );                    } catch (IOException ioe) {}                }            }        }    }}

另外,我们也可以使用InterruptibleChannel接口。 实现了InterruptibleChannel接口的类可以在阻塞的时候抛出ClosedByInterruptException。如:

package com.cnblogs.gpcuster

import java.io.BufferedReader;import java.io.FileDescriptor;import java.io.FileInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.channels.Channels;

public class InterruptInput {       static BufferedReader in = new BufferedReader(            new InputStreamReader(            Channels.newInputStream(            (new FileInputStream(FileDescriptor.in)).getChannel())));

public static void main(String args[]) {        try {            System.out.println("Enter lines of input (user ctrl+Z Enter to terminate):");            System.out.println("(Input thread will be interrupted in 10 sec.)");            // interrupt input in 10 sec
            (new TimeOut()).start();            String line = null;            while ((line = in.readLine()) != null) {                System.out.println("Read line:‘"+line+"‘");            }        } catch (Exception ex) {            System.out.println(ex.toString()); // printStackTrace();
        }
    }

    public static class TimeOut extends Thread {        int sleepTime = 10000;        Thread threadToInterrupt = null;            public TimeOut() {            // interrupt thread that creates this TimeOut.
            threadToInterrupt = Thread.currentThread();
            setDaemon(true);        }

public void run() {            try {                sleep(10000); // wait 10 sec
            } catch(InterruptedException ex) {/*ignore*/}            threadToInterrupt.interrupt();        }    }}

这里还需要注意一点,当线程处于写文件的状态时,调用interrupt()不会中断线程。

来源: <http://www.cnblogs.com/gpcuster/archive/2010/01/18/1650273.html>

来自为知笔记(Wiz)

时间: 2024-10-08 20:24:08

如何停止JAVA线程的相关文章

停止Java线程,小心interrupt()方法

程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误. 在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 背景     中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果.你最好还是牢记以下的几点告诫. 首先,忘掉

浅析Java线程的正确停止

线程错误终止之destroy与stop方法 记得以前初学Java的时候,由于缺少对锁.同步.异步等这些线程的知识,想当然的以为destroy与stop方法都能正确的停止Java线程的执行.但是,后来随着工作的积累,以及对线程安全的一些理解,慢慢认识到这两个方法是有问题的,并且这两方法也早已在java doc上被指名是弃用的. destroy()这个方法其实根本没干什么事情,只是抛出了一个NoSuchMethodError,所以说该方法无法终止线程,因此不能望文生意: /** * Throws {

java线程中断

java线程中断[interrupt()函数] http://vikings825.iteye.com/blog/964644 停止Java线程,小心interrupt()方法  这篇写的是怎么  正确的 停止 一个线程 http://blog.csdn.net/wxwzy738/article/details/8516253 聊聊并发——生产者消费者模式 http://www.infoq.com/cn/articles/producers-and-consumers-mode/

如何终止java线程

终止线程的三种方法 有三种方法可以使终止线程. 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resume一样,也可能发生不可预料的结果). 3.  使用interrupt方法中断线程. 1. 使用退出标志终止线程 当run方法执行完后,线程就会退出.但有时run方法是永远不会结束的.如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务.在这种情况下,一般是将这

[转]JAVA线程停止的方法

有三种方法可以使终止线程. 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resume一样,也可能发生不可预料的结果). 已废弃 3.  使用interrupt方法中断线程. 如何停止java的线程一直是一个困恼我们开发多线程程序的一个问题.这个问题最终在Java5的java.util.concurrent中得到了回答:使用interrupt(),让线程在run方法中停止. 简介

Java并发(基础知识)—— 创建、运行以及停止一个线程

0.介绍 在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的操作系统都允许并发地执行任务.你可以在听音乐和浏览网页新闻的同时阅读邮件,我们说这种并发是进程级别的并发.而且在同一进程内,也会同时有多种任务,这些在同一进程内运行的并发任务称之为线程. 在这里我们要讨论的是线程级并发.Java提供了Thread类,使我们能够在一个Java进程中运行多个线

java停止一个线程

Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的interrupt()方中断阻塞,线程开始检查标志(PS:抛出异常不会退出循环) ------------------------------------------------------------我是copy分割线------------------------------------------

Java线程状态、线程停止、线程阻塞

线程状态(五种状态) Java 线程的生命周期包括创建,就绪,运行,阻塞,死亡5 个状态.一个 Java 线程总是处于这 5 个生命周期状态之一,并在一定条件下可以在不同状态之间进行转换 . 创建状态 (New Thread) 在 Java 语言中使用 new操作符创建一个线程后,该线程仅仅是一个空对象,它具备了线程的一些特征,但此时系统没有为其分配资源,这时的线程处于创建状态. 就绪状态 (Runnable) 使用 start()方法启动一个线程后,系统为该线程分配了除 CPU 外的所需资源,

如何停止一个正在运行的java线程

与此问题相关的内容主要涉及三部分:已废弃的Thread.stop().迷惑的thread.interrupt系列.最佳实践Shared Variable. 已废弃的Thread.stop() @Deprecated public final void stop() { stop(new ThreadDeath()); } 如上是Hotspot JDK 7中的java.lang.Thread.stop()的代码,学习一下它的doc: 该方法天生是不安全的.使用thread.stop()停止一个线程