程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 如何停止java線程

如何停止java線程

編輯:關於JAVA

簡介

在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()不會中斷線程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved