在循环中调用 url.openStream() 时停止线程执行

Stop thread execution when it calls url.openStream() in a loop

编辑:我知道Thread.interrupt() 的作用。

应用程序创建一个 Thread 连续读取 一个 URL。 3 秒后 Thread 被打断但不幸的是继续执行。

如何停止线程执行?

代码(Main.java,MyRunnable.java):

public class Main {

    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable("http://ninjaflex.com/");
        Thread thread = new Thread(runnable);
        thread.start();
        sleep(3000);
        thread.interrupt();
        System.out.println("Thread.interrupt() invoked.");
    }

    private static void sleep(long timeMilli) {
        try {
            Thread.sleep(timeMilli);
        } catch (Exception e) {

        }
    }
}

public class MyRunnable implements Runnable {

    private String website;

    MyRunnable(String website) {
        this.website = website;
    }

    @Override
    public void run() {
        URL url = createUrl();
        if (url != null) {
            while (!Thread.currentThread().isInterrupted()) {
                sleepOneSec();
                readFromUrl(url);
                System.out.println("Read from " + website);
            }
            System.out.println("Script: Interrupted, exiting.");
        }
    }

    private URL createUrl() {
        URL url = null;
        try {
            url = new URL(website);
        } catch (MalformedURLException e) {
            System.out.println("Wrong URL?");
        }
        return url;
    }

    private void sleepOneSec() {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            System.out.println("Error sleeping");
        }
    }

    private void readFromUrl(URL url) {
        InputStream in = null;
        try {
            in = url.openStream();
        } catch (Exception e) {
            System.out.println("Exception while url.openStream().");
            e.printStackTrace();
        } finally {
            closeInputStream(in);
        }
    }

    private void closeInputStream(InputStream in) {
        try {
            in.close();
        } catch (IOException e) {
            System.out.println("Error while closing the input stream.");
        }
    }
}

基本上,您的 MyRunnable 线程在睡眠期间被中断。 InterreuptedException 被抛出但被捕获。顺便说一下,捕捉 Exception 是一个坏习惯,你不应该那样做。 来自 javadoc:"The interrupted status of the current thread is cleared when this exception is thrown"。 因此,您的 while 循环永远不会看到标志。

我删除了 MyRunnable.sleepOneSec,您的代码开始工作了。

用简单的 Thread.sleep 调用替换对 sleepOneSec 方法的调用。在 while 循环外 捕获 InterruptedException。这将导致循环自然退出:

try {
    while (true) {
        Thread.sleep(1000);
        readFromUrl(url);
        System.out.println("Read from " + website);
    }
} catch (InterruptedException e) {
    System.out.println("Script: Interrupted, exiting.");
}