简体   繁体   English

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

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

I have this problem: I am getting some data in an android asynctask from multiple urls using Jsoup.connect(url).get() and then showing it in an Activity. 我有这个问题:我使用Jsoup.connect(url).get()从多个url获取android asynctask中的一些数据,然后在Activity中显示它。 The problem is that sometimes i need to interrupt the threads and free the processor before getting the jsoup result or catching a timeout exception. 问题是有时我需要在获取jsoup结果或捕获超时异常之前中断线程并释放处理器。

The important part of the code code looks like this: 代码的重要部分如下所示:

    @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]);
    }

The reason i am using a Thread pool executor is that it does the connections in multiple threads in parallel, instead of waiting for one result and the opening a second connection and so on. 我使用线程池执行程序的原因是它并行处理多个线程中的连接,而不是等待一个结果并打开第二个连接,依此类推。

I tried doing cancel(true); 我尝试cancel(true); OR threadPoolExecutor.shutDown(); 或者threadPoolExecutor.shutDown(); and threadPoolExecutor.shutDownNow(); threadPoolExecutor.shutDownNow(); on a button, which was set in onPreExecute but it did not stop the Runnable s. 在一个按钮上,它在onPreExecute中设置但它没有停止Runnable Even when i close the activity, the Runnable s continue to run until they timeout and until then i can not do anything on the network because the jsoup connections are still running. 即使我关闭活动, Runnable继续运行直到它们超时,直到那时我在网络上无法做任何事情,因为jsoup连接仍在运行。 Please point me in the right direction. 请指出我正确的方向。 Many thanks and i apologize if this is a really stupid question but i could not find a similar one here. 非常感谢,如果这是一个非常愚蠢的问题我很抱歉,但我在这里找不到类似的问题。

In short: I need to stop the threads when the AsyncTask cancels. 简而言之:我需要在AsyncTask取消时停止线程。

ThreadPoolExecutor is a general purpose executor that needs some experience to configure. ThreadPoolExecutor是一个通用的执行程序,需要一些经验来配置。 It's a gateway for those experienced programmers whose needs are not satisfied (after enough testing) by the executors returned by other factory methods in the Executors class. 这对于那些有经验的程序员,他们的需求是不被满足(足够的测试之后)由遗嘱执行人由其他工厂方法返回一个网关Executors类。 The Javadoc for one of the constructors of this class even documents it: 这个类的构造函数之一的Javadoc甚至记录了它:

It may be more convenient to use one of the {@link Executors} factory methods instead of this general purpose constructor. 使用{@link Executors}工厂方法之一而不是这个通用构造函数可能更方便。

Are you convinced that you still want to use ThreadPoolExector ? 你确信你还想使用ThreadPoolExector吗? Note that you can always provide to the methods of the Executors the ThreadFactory that creates the actual threads that run your async tasks. 请注意,您始终可以向Executors的方法提供ThreadFactory ,该方法创建运行异步任务的实际线程。 You do not have to go to ThreadPoolExecutor . 您不必去ThreadPoolExecutor

In your call above, you make every thread wait 30 seconds ( keepAliveTime ) which makes it wait idly before termination. 在上面的调用中,您使每个线程等待30秒( keepAliveTime ),这使得它在终止之前等待空闲。 Are you sure you want that? 你确定要的吗?

You also use just Runnable instances as your tasks. 您还只使用Runnable实例作为您的任务。 Had you considered using Callable instances instead, you could have used submit method which returns a Future which can be canceled. 如果您考虑使用Callable实例,则可以使用submit方法返回可以取消的Future This also facilitates the use of invokeAll() method that lets you pass in a collection of Callable s and query/cancel the returned Future s. 这也便于使用invokeAll()方法,该方法允许您传入Callable的集合并查询/取消返回的Future You said above that you did cancel(true) , but note that that method is only available on a Future . 你上面说过你确实cancel(true) ,但请注意,该方法仅适用于Future

A reliable way to shut down an executor or executor service is: 关闭执行程序或执行程序服务的可靠方法是:

  • Shut it down to attempt orderly shutdown using the shutdown() method. 将其关闭以尝试使用shutdown()方法有序关闭。
  • Await its termination. 等待终止。
  • Only if needed, shut it down now using the shutdownNow() method and if you did, handle the returned list of Runnable s properly. 只有在需要时, 现在使用shutdownNow()方法将其shutdownNow() ,如果这样做,请正确处理返回的Runnable列表。
  • Handle the exceptions well (this needs to be emphasized). 处理好例外(这需要强调)。 I am sure that Jsoup.connect throws various different exceptions and you should handle them correctly. 我确信Jsoup.connect会抛出各种不同的异常,你应该正确处理它们。 In you case, sadly, you even name the exception variable ignored ! 在你的情况下,遗憾的是,你甚至ignored了异常变量的名称! Please don't believe everything you read on the Internet ;). 请不要相信您在互联网上阅读的所有内容;)。

After you have gotten some experience with ExecutorService this way, you can move on to CompletionService which provides Future s as the async tasks complete . 通过这种方式获得ExecutorService一些经验之后,您可以继续使用CompletionService ,它可以在CompletionService 异步任务时提供Future This exploits parallelism rather better especially if the tasks consist of variable IO-bound activity. 这会更好地利用并行性,尤其是当任务由可变的IO绑定活动组成时。

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

相关问题 我怎样才能立即终止一个线程? (不中断) - How can I immediately terminate a Thread? (Not interrupt) 我怎么能理解Thread.interrupt()? - How can i understand Thread.interrupt()? 如何使用 jsoup 获取 img src? - How can I get img src with jsoup? 如何不使用不赞成使用的方法来中断和恢复线程? - How can I interrupt and resume a thread without the use of deprecated methods? 如何中断从方法内部创建的线程? - How can I interrupt a thread created from within a method? 如何使用Postgresql中断运行JDBC查询的线程? - How can I interrupt a thread running JDBC query with Postgresql? 一旦我的线程中断,我怎么能中断RestTemplate调用? - How can I interrupt RestTemplate call as soon as my thread is interrupted? 如何在 Java 中有理由中断线程/未来/执行程序? - How can I interrupt a thread/future/executor with reason in Java? 如何在jsoup中找到带有pseudoElement ::before的HTML标签 - How can I find a HTML tag with the pseudoElement ::before in jsoup 如何使用 executor.execute 和 future.get() 结束任务(使线程超时)(通过上升中断)而不阻塞主线程 - How to end a task(timeout a thread) (by rising interrupt) using executor.execute and future.get() without blocking the main thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM