[转]JAVA线程停止的方法

有三种方法可以使终止线程。

1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。 已废弃

3.  使用interrupt方法中断线程。

如何停止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()不会中断线程。

参考资料

How to Stop a Thread or a Task

Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

时间: 2024-12-29 01:55:47

[转]JAVA线程停止的方法的相关文章

java 线程停止的方法

线程停止的方法: 记住一点,线程的停止, 1.自己运行完了, 2.如果是无限循环,在外部,只能用flag标记来操作. 但是当线程处于冻结状态(阻塞),sleep,wait,join,(这三个方法抛出异常.) 就不会读取到flag. 这个时候,我们要清除线程的冻结状态,让它回到运行中. 如果,线程没有使之冻结的语句,则,inierrupt()不进行任何操作. interrupt()方法,会使sleep,wait,jion方法抛出异常. 然后,我们在处理异常的语句中来操作. 我推荐的方式:不在cat

java线程停止的方法

之前介绍过,停机线程可以使用interrupte ,可以用标记,让run执行结束.现在我们来看几个方法. 方法1.使用interrupte方法来执行,通过抛出InterruptedException来结束run运行. package secondThreadStudy; import java.lang.InterruptedException; public class MyThread extends Thread { @Override public void run(){ super.r

Java 线程停止、暂停和继续

Thread 类中停止线程的方法有 stop(),暂停和继续线程的方法有 suspend() 和 resume().然而这些方法已经被废弃了. 异常法停止线程 上代码: public class Test { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); try { Thread.sleep(1000); } catch (InterruptedExceptio

Thread的中断机制(interrupt),循环线程停止的方法

一.中断原理 中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序本身.线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true).它并不像stop方法那样会中断一个正在运行的线程. 判断线程是否被中断 判断某个线程是否已被发送过中断请求,请使用Thread.currentThread().isInterrupted()方法(因为它将

Java线程死锁解决方法(转)

转自:http://leowzy.iteye.com/blog/740859 Java线程死锁如何避免这一悲剧  Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键.不幸的是,使用上锁会带来其他问题.让我们来看一些常见问题以及相应的解决方法: Java线程死锁 Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待那些根本不可能被释放的锁,从而导致所有的工作都无法完成.假设有两个线程,分别代表两个饥饿的人,他们必须共享刀叉并轮流吃饭.他们都需要获得两个锁:共享

从头认识多线程-1.8 迫使线程停止的方法-暴力Stop方法

这一章节我们来讨论一下暴力Stop方法. 1.使用样例 package com.ray.deepintothread.ch01.topic_8; public class StopByStopMethod { @SuppressWarnings("deprecation") public static void main(String[] args) throws InterruptedException { ThreadFive threadFive = new ThreadFive

java线程相关基本方法

java线程中常用的基本方法有wait,notify,notifyAll,sleep,join,yield等. 线程的生命周期一共分为五个部分,分别是:新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead).由于cpu需要在多条线程中切换因此线程状态也会在多次运行和阻塞之间切换. 线程等待(wait) 调用该方法会使线程会进入WAITING状态,只有等待另外线程的通知或者被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁,所以,

java 线程的使用方法

一.使用线程的三种基本方法 1.扩展Thread类 public class Mythread extends Thread{ public void run(){ System.out.println("拓展thread类"); } } //启动线程 Thread myThread =new Thread(); MyThread.start(); 2.实现Runnable接口 public class Mythread implements Runnable{ public MyCl

从头认识多线程-1.9 迫使线程停止的方法-return法

这一章节我们来讨论一下还有一种停止线程的方法-return 1.在主线程上面return,是把全部在执行的线程都停掉 package com.ray.deepintothread.ch01.topic_9; public class StopByReturn { public static void main(String[] args) throws InterruptedException { ThreadFive threadFive = new ThreadFive(); Thread