为什么这个Java程序挂起(异步html下载程序)?

为什么这个Java程序挂起(异步html下载程序)?,java,multithreading,asynchronous,Java,Multithreading,Asynchronous,你能告诉我为什么这个Java程序挂起吗? 这是一个使用ExecutorCompletionService异步下载HTML的简单程序。我试图使用executor.shutdown()和completionService.shutdown(),但两者都没有给出这样的方法。我认为问题出在executor和completionService上,但不使用关机方法无法找到如何阻止它们 import java.io.BufferedReader; import java.io.InputStreamReade

你能告诉我为什么这个Java程序挂起吗? 这是一个使用ExecutorCompletionService异步下载HTML的简单程序。我试图使用
executor.shutdown()
completionService.shutdown()
,但两者都没有给出这样的方法。我认为问题出在
executor
completionService
上,但不使用关机方法无法找到如何阻止它们

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.net.URL;
import java.util.concurrent.*;

class Main {

    public static void main(String[] args) throws Exception {

        Executor executor = Executors.newFixedThreadPool(2);
        CompletionService<String> completionService = new ExecutorCompletionService<>(executor);
        completionService.submit(new GetPageTask(new URL("http://xn--80adxoelo.xn--p1ai/")));//slow web site
        completionService.submit(new GetPageTask(new URL("http://example.com")));

        Future<String> future = completionService.take();
        System.out.println(future.get());

        Future<String> future2 = completionService.take();
        System.out.println(future2.get());


    }
}

final class GetPageTask implements Callable<String> {
    private final URL url;

    GetPageTask(URL url) {
        this.url = url;
    }

    private String getPage() throws Exception {
        final BufferedReader reader = new BufferedReader(new InputStreamReader(this.url.openStream()));
        String str = "";
        String line;
        while ((line = reader.readLine()) != null) {
            str += line + "\n";
        }
        reader.close();
        return str;
    }

    @Override
    public String call() throws Exception {
        return getPage();
    }
}
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.net.URL;
导入java.util.concurrent.*;
班长{
公共静态void main(字符串[]args)引发异常{
Executor Executor=Executors.newFixedThreadPool(2);
CompletionService CompletionService=新的执行者CompletionService(执行者);
completionService.submit(新的GetPageTask(新的URL)(“http://xn--80adxoelo.xn--p1ai/);//速度慢的网站
completionService.submit(新的GetPageTask(新的URL)(“http://example.com")));
Future=completionService.take();
System.out.println(future.get());
Future future2=completionService.take();
System.out.println(future2.get());
}
}
最后一个类GetPageTask实现可调用{
私有最终URL;
GetPageTask(URL){
this.url=url;
}
私有字符串getPage()引发异常{
final BufferedReader=new BufferedReader(new InputStreamReader(this.url.openStream());
字符串str=“”;
弦线;
而((line=reader.readLine())!=null){
str+=第+“\n”行;
}
reader.close();
返回str;
}
@凌驾
公共字符串调用()引发异常{
返回getPage();
}
}
的javadoc表示它返回
ExecutorService
的实例。的javadoc显示它有一个
shutdown()
方法

您无法访问它,因为您选择将变量声明为
Executor
而不是
ExecutorService

就像你做的那样

Object o = new Integer(34);
Integer o = new Integer(34);
您将无法在
o
上调用任何整数方法。如果你这样做了

Object o = new Integer(34);
Integer o = new Integer(34);
然后可以在o上使用整数方法


我不想粗鲁,但这是在考虑多线程编程之前应该掌握的基本知识,这是非常非常复杂的。

如何?有打印什么吗?谢谢。将Executor替换为ExecutorService并添加了关机。现在没事了。