[英]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: 关闭执行程序或执行程序服务的可靠方法是:
shutdown()
method. 将其关闭以尝试使用shutdown()
方法有序关闭。 shutdownNow()
method and if you did, handle the returned list of Runnable
s properly. 只有在需要时, 现在使用shutdownNow()
方法将其shutdownNow()
,如果这样做,请正确处理返回的Runnable
列表。 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.