在循环中调用 url.openStream() 时停止线程执行
Stop thread execution when it calls url.openStream() in a loop
编辑:我知道Thread.interrupt() 的作用。
当我中断线程时,while (!Thread.currentThread().isInterrupted())
不会退出。
- 我也尝试从 url.openStream() 捕获异常;当。。。的时候
线程被中断(无奈,可能是阻塞方法,
这不是)并退出循环,没有任何成功。
应用程序创建一个 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.");
}
编辑:我知道Thread.interrupt() 的作用。
-
当我中断线程时,
while (!Thread.currentThread().isInterrupted())
不会退出。- 我也尝试从 url.openStream() 捕获异常;当。。。的时候 线程被中断(无奈,可能是阻塞方法, 这不是)并退出循环,没有任何成功。
应用程序创建一个 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.");
}