Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在超时之前中断Jsoup get线程?_Java_Android_Multithreading_Android Asynctask_Jsoup - Fatal编程技术网

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绑定活动时