在Java中,是否可以执行一个方法一段时间,并在达到时间限制后停止?

发布于 2024-11-10 13:11:56 字数 609 浏览 1 评论 0原文

我有这段下载网页的代码:

HttpURLConnection connection;

private String downloadContent() {
    InputStream content;
    Source parser;
    try {
        content = connection.getInputStream(); //<--here is the download
        parser = new Source(content);            
        content.close();
        return parser.toString();
    } catch (Exception e) {
        return null;
    }
}

在下载时,我尝试获取下载的数据量,如果达到限制,我会停止下载,但我没有找到一种方法来做到这一点。如果有人知道该怎么做,请告诉我。

现在我想限制下载时间。示例:如果下载超过 20 秒,我就会停止它。我想这样做是因为我的程序是一个网络爬虫,如果出现错误,它会开始下载一个大文件,它将卡在下载中,这不是我想要做的,所以欢迎按大小过滤下载,但我不知道,过滤时间可以防止这个问题。

I have this code that downloads a web page:

HttpURLConnection connection;

private String downloadContent() {
    InputStream content;
    Source parser;
    try {
        content = connection.getInputStream(); //<--here is the download
        parser = new Source(content);            
        content.close();
        return parser.toString();
    } catch (Exception e) {
        return null;
    }
}

While doing the download, I tried to get the amount of downloaded data, and if it reaches a limit, I stop the downloading, but I not found a way to do this. If someone know how to do, please tell me.

Now I want to limit the download time. Example: if the download pass 20 seconds, I stop it. I want to do this because my program it's an webcrawler and if by an error, it begins downloading a big file, it will stuck in the download, and is not this I want to do, so a filter in download by size is welcome, but as I don't know, a filter time will prevent this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

七秒鱼° 2024-11-17 13:11:56

实现这一目标的正确方法如下:

public class TimeOut {

    public static class MyJob implements Callable<String> {

        @Override
        public String call() throws Exception {
            // Do something
            return "result";
        }

    }

    public static void main(String[] args) {

        Future<String> control
                = Executors.newSingleThreadExecutor().submit(new MyJob());

        try {

            String result = control.get(5, TimeUnit.SECONDS);

        } catch (TimeoutException ex) {

            // 5 seconds expired, we cancel the job !!!
            control.cancel(true);

        }
        catch (InterruptedException ex) {

        } catch (ExecutionException ex) {

        }

    }

}

The proper way to achieve this is the following:

public class TimeOut {

    public static class MyJob implements Callable<String> {

        @Override
        public String call() throws Exception {
            // Do something
            return "result";
        }

    }

    public static void main(String[] args) {

        Future<String> control
                = Executors.newSingleThreadExecutor().submit(new MyJob());

        try {

            String result = control.get(5, TimeUnit.SECONDS);

        } catch (TimeoutException ex) {

            // 5 seconds expired, we cancel the job !!!
            control.cancel(true);

        }
        catch (InterruptedException ex) {

        } catch (ExecutionException ex) {

        }

    }

}
孤凫 2024-11-17 13:11:56

您可以使用 AOP 和 @Timeable来自 jcabi-aspects 的注释(我是开发人员):

@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String downloadContent() {
  if (Thread.currentThread.isInterrupted()) {
    throw new IllegalStateException("time out");
  }
  // download
}

请注意,您应该定期检查 isInterrupted() ,并在其设置为 TRUE 时抛出异常。这是 Java 中终止线程的唯一方法。

另外,有关更详细的说明,请查看这篇文章: http: //www.yegor256.com/2014/06/20/limit-method-execution-time.html

You can use AOP and a @Timeable annotation from jcabi-aspects (I'm a developer):

@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String downloadContent() {
  if (Thread.currentThread.isInterrupted()) {
    throw new IllegalStateException("time out");
  }
  // download
}

Pay attention that you should check for isInterrupted() regularly and throw an exception when it is set to TRUE. This is the only way to terminate a thread in Java.

Also, for more detailed explanation, check this post: http://www.yegor256.com/2014/06/20/limit-method-execution-time.html

柠栀 2024-11-17 13:11:56

有一个指定的类 java.util.Timer 旨在执行您所需的任务。您可以参考 API 了解更多详细信息。

There is a specified class java.util.Timer that is intended to do the tasks you required.You can reference the API for more detail.

清音悠歌 2024-11-17 13:11:56

生活很混乱。如果你想自己清理干净,需要做一些工作。

private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(20);
private String downloadContent() {
  connection.setConnectTimeout(TIMEOUT); /* Set connect timeout. */
  long start = System.nanoTime(); 
  final InputStream content;
  try {
    content = connection.getInputStream();
  } catch (IOException ex) { 
    return null;
  }
  /* Compute how much time we have left. */
  final long delay = TIMEOUT - 
    TimeUnit.NANOS.toMillis(System.nanoTime() - time); 
  if (delay < 1)
    return null;
  /* Start a thread that can close the stream asynchronously. */
  Thread killer = new Thread() {
    @Override
    public void run() {
      try {
        Thread.sleep(delay); /* Wait until time runs out or interrupted. */
      } catch (InterruptedException expected) { 
        Thread.currentThread().interrupt();
      }
      try {
        content.close();
      } catch (IOException ignore) {
        // Log this?
      }
    }
  };
  killer.start();
  try {
    String s = new Source(content).parser.toString();
    /* Task completed in time; clean up immediately. */
    killer.interrupt();
    return s;
  } catch (Exception e) {
    return null;
  }
}

Life is messy. If you want to clean up after yourself, it takes some work.

private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(20);
private String downloadContent() {
  connection.setConnectTimeout(TIMEOUT); /* Set connect timeout. */
  long start = System.nanoTime(); 
  final InputStream content;
  try {
    content = connection.getInputStream();
  } catch (IOException ex) { 
    return null;
  }
  /* Compute how much time we have left. */
  final long delay = TIMEOUT - 
    TimeUnit.NANOS.toMillis(System.nanoTime() - time); 
  if (delay < 1)
    return null;
  /* Start a thread that can close the stream asynchronously. */
  Thread killer = new Thread() {
    @Override
    public void run() {
      try {
        Thread.sleep(delay); /* Wait until time runs out or interrupted. */
      } catch (InterruptedException expected) { 
        Thread.currentThread().interrupt();
      }
      try {
        content.close();
      } catch (IOException ignore) {
        // Log this?
      }
    }
  };
  killer.start();
  try {
    String s = new Source(content).parser.toString();
    /* Task completed in time; clean up immediately. */
    killer.interrupt();
    return s;
  } catch (Exception e) {
    return null;
  }
}
自找没趣 2024-11-17 13:11:56

您无法停止正在运行的线程。但是,您可以执行以下操作:

1) 创建一个新线程并从此线程中获取内容。如果线程回答的时间太长,则继续并忽略其结果。这种方法的缺点:后台线程仍然会下载大文件。

2) 使用另一个具有更多控件的HTTP连接API。我很久以前就使用过“Jakarta Commons HttpClient”,并且对其超时能力非常满意。

You can't stop a running thread. What you can do, however:

1) Create a new thread and fetch the content from this thread. If the thread takes too long to answer, just go on and ignore its results. Downside of this approach: the background thread will still download the big file.

2) Use another HTTP connection API with more controls. I've used "Jakarta Commons HttpClient" a long time ago and was very pleased with its ability to timeout.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文