• 如何停止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) {}

                threadToInterrupt.interrupt();

            }

        }

    }



  • 相关阅读:
    HDFS上传下载API
    HDFS2.X新特性:HA和Federation联盟
    HDFS2.X架构及工作原理
    浅析Secondary NameNode与namenode
    Flink安装部署
    HDFS基本命令行操作与简单API实用
    Linux基础_Hadoop环境搭建必备
    HBase BlockCache机制讲解
    HDFS集群安装部署
    我亦未曾饶过岁月_面试总结
  • 原文地址:https://www.cnblogs.com/luckForever/p/7254215.html
Copyright © 2020-2023  润新知