Java 如何在超时之前中断Jsoup get线程?
我有一个问题: 我使用Java 如何在超时之前中断Jsoup get线程?,java,android,multithreading,android-asynctask,jsoup,Java,Android,Multithreading,Android Asynctask,Jsoup,我有一个问题: 我使用Jsoup.connect(url).get()从多个url获取android asynctask中的一些数据,然后将其显示在活动中。问题是,有时我需要在获得jsoup结果或捕获超时异常之前中断线程并释放处理器 代码的重要部分如下所示: @Override protected Void doInBackground(String... urls) { int cpuCount = Runtime.getRuntime().availa
Jsoup.connect(url).get()
从多个url获取android asynctask中的一些数据,然后将其显示在活动中。问题是,有时我需要在获得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]);
}
@覆盖
受保护的Void doInBackground(字符串…URL){
int cpuCount=Runtime.getRuntime().availableProcessors();
BlockingQueue=新建LinkedBlockingQueue();
ThreadPoolExecutor ThreadPoolExecutor=新的ThreadPoolExecutor(
cpuCount,
cpuCount,
30,
时间单位:秒,
排队);
final CountDownLatch CountDownLatch=新的CountDownLatch(url.length);
for(最终字符串url:url){
threadPoolExecutor.execute(新的Runnable(){
@凌驾
公开募捐{
字符串html=null;
试一试{
html=Jsoup.connect(url.get().outerHtml();
}捕获(忽略异常){
}
如果(html!=null){
出版进度(视频流);
}
countdownlock.countDown();
}
});
}
倒计时闩锁。等待();
返回null;
}
@凌驾
受保护的void onProgressUpdate(字符串…结果){
updateUiStuff(结果[0]);
}
我使用线程池执行器的原因是它并行地在多个线程中执行连接,而不是等待一个结果并打开第二个连接等等
我试过做cancel(true)代码>或线程池执行器.shutDown()代码>和线程池执行器.shutDownNow()按钮上的代码>,该按钮在onPreExecute中设置,但它没有停止可运行
s。即使在我关闭活动时,Runnable
s仍会继续运行,直到超时,在此之前,我无法在网络上执行任何操作,因为jsoup连接仍在运行。请给我指一下正确的方向。非常感谢,如果这是一个非常愚蠢的问题,我道歉,但我在这里找不到类似的问题
简而言之:当异步任务取消时,我需要停止线程。ThreadPoolExecutor
是一个通用执行器,需要一些经验来配置。对于那些有经验的程序员来说,它是一个网关,这些程序员的需求(经过足够的测试)不能被executors
类中其他工厂方法返回的executors满足。此类构造函数之一的Javadoc甚至记录了它:
使用{@link Executors}
工厂之一可能更方便
方法而不是此通用构造函数
您是否确信仍要使用ThreadPoolExector
?请注意,您始终可以向执行器
的方法提供创建运行异步任务的实际线程的线程工厂
。您不必转到ThreadPoolExecutor
在上面的调用中,您让每个线程等待30秒(keepAliveTime),这使得它在终止之前等待得很慢。你确定你想要吗
您还可以仅使用Runnable
实例作为任务。如果您考虑改为使用Callable
实例,您可以使用submit
方法,该方法返回一个可以取消的Future
。这也有助于使用invokeAll()
方法,该方法允许您传入Callable
s的集合,并查询/取消返回的Future
s。您在上面说过您确实执行了取消(true)
,但请注意,该方法仅适用于未来的
关闭executor或executor服务的可靠方法是:
- 关闭它以尝试使用
shutdown()
方法有序关闭
- 等待它的终止
- 仅在需要时,立即使用
shutdownNow()
方法将其关闭,如果关闭了,请正确处理返回的Runnable
s列表
- 很好地处理异常(需要强调这一点)。我确信
Jsoup.connect
会抛出各种不同的异常,您应该正确处理它们。不幸的是,您甚至将异常变量命名为“忽略”
!请不要相信你在网上看到的一切;)李>
通过这种方式获得ExecutorService
的一些经验后,您可以转到CompletionService
,它在异步任务完成时提供Future
s。这可以更好地利用并行性,特别是当任务包含可变的IO绑定活动时