繁体   English   中英

如何在超时之前中断Jsoup get线程?

[英]How can I interrupt a Jsoup get thread before the timeout?

我有这个问题:我使用Jsoup.connect(url).get()从多个url获取android asynctask中的一些数据,然后在Activity中显示它。 问题是有时我需要在获取jsoup结果或捕获超时异常之前中断线程并释放处理器。

代码的重要部分如下所示:

    @Override
    protected Void doInBackground(String... urls) {
            int cpuCount = Runtime.getRuntime().availableProcessors();

            BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                    cpuCount,
                    cpuCount,
                    30,
                    TimeUnit.SECONDS,
                    queue);

            final CountDownLatch countDownLatch = new CountDownLatch(urls.length);

            for (final String url : urls) {
                threadPoolExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        String html = null;
                        try {
                            html = Jsoup.connect(url).get().outerHtml();
                        } catch (Exception ignored) {
                        }

                        if (html != null) {
                            publishProgress(videoStream);
                        }
                        countDownLatch.countDown();
                    }
                });
            }
        countDownLatch.await();
        return null;
    }

    @Override
    protected void onProgressUpdate(String... result) {
        updateUiStuff(result[0]);
    }

我使用线程池执行程序的原因是它并行处理多个线程中的连接,而不是等待一个结果并打开第二个连接,依此类推。

我尝试cancel(true); 或者threadPoolExecutor.shutDown(); threadPoolExecutor.shutDownNow(); 在一个按钮上,它在onPreExecute中设置但它没有停止Runnable 即使我关闭活动, Runnable继续运行直到它们超时,直到那时我在网络上无法做任何事情,因为jsoup连接仍在运行。 请指出我正确的方向。 非常感谢,如果这是一个非常愚蠢的问题我很抱歉,但我在这里找不到类似的问题。

简而言之:我需要在AsyncTask取消时停止线程。

ThreadPoolExecutor是一个通用的执行程序,需要一些经验来配置。 这对于那些有经验的程序员,他们的需求是不被满足(足够的测试之后)由遗嘱执行人由其他工厂方法返回一个网关Executors类。 这个类的构造函数之一的Javadoc甚至记录了它:

使用{@link Executors}工厂方法之一而不是这个通用构造函数可能更方便。

你确信你还想使用ThreadPoolExector吗? 请注意,您始终可以向Executors的方法提供ThreadFactory ,该方法创建运行异步任务的实际线程。 您不必去ThreadPoolExecutor

在上面的调用中,您使每个线程等待30秒( keepAliveTime ),这使得它在终止之前等待空闲。 你确定要的吗?

您还只使用Runnable实例作为您的任务。 如果您考虑使用Callable实例,则可以使用submit方法返回可以取消的Future 这也便于使用invokeAll()方法,该方法允许您传入Callable的集合并查询/取消返回的Future 你上面说过你确实cancel(true) ,但请注意,该方法仅适用于Future

关闭执行程序或执行程序服务的可靠方法是:

  • 将其关闭以尝试使用shutdown()方法有序关闭。
  • 等待终止。
  • 只有在需要时, 现在使用shutdownNow()方法将其shutdownNow() ,如果这样做,请正确处理返回的Runnable列表。
  • 处理好例外(这需要强调)。 我确信Jsoup.connect会抛出各种不同的异常,你应该正确处理它们。 在你的情况下,遗憾的是,你甚至ignored了异常变量的名称! 请不要相信您在互联网上阅读的所有内容;)。

通过这种方式获得ExecutorService一些经验之后,您可以继续使用CompletionService ,它可以在CompletionService 异步任务时提供Future 这会更好地利用并行性,尤其是当任务由可变的IO绑定活动组成时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM