多线程java优化

多线程java优化,java,multithreading,performance,Java,Multithreading,Performance,在我的程序中,我试图掌握如何使用ExecutorService优化我的程序。 由于某些原因,它在两个URL上有点卡住了。和。当它位于这两个URL上时,它不会继续执行其他URL 即使这两个域的响应速度不够快,其他3个可用线程是否也不能继续 如何以最好的方式解决这个问题 public class SequentialPinger { public static void main(String args[]) throws Exception { String[] host

在我的程序中,我试图掌握如何使用ExecutorService优化我的程序。 由于某些原因,它在两个URL上有点卡住了。和。当它位于这两个URL上时,它不会继续执行其他URL

即使这两个域的响应速度不够快,其他3个可用线程是否也不能继续

如何以最好的方式解决这个问题

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

        String[] hostList = {"http://crunchify.com", "http://yahoo.com",
            "http://www.ebay.com", "http://google.com",
            "http://www.example.co", "https://paypal.com",
            "http://bing.com/", "http://techcrunch.com/",
            "http://mashable.com/", "http://thenextweb.com/",
            "http://wordpress.com/", "http://cphbusiness.dk/",
            "http://example.com/", "http://sjsu.edu/",
            "http://ebay.co.uk/", "http://google.co.uk/",
            "http://www.wikipedia.org/",
            "http://dr.dk", "http://pol.dk", "https://www.google.dk",
            "http://phoronix.com", "http://www.webupd8.org/",
            "https://studypoint-plaul.rhcloud.com/", "http://stackoverflow.com",
            "http://docs.oracle.com", "https://fronter.com",
            "http://imgur.com/", "http://www.imagemagick.org"
        };

        List<CallableImpl> callList = new ArrayList();
        ExecutorService es = Executors.newFixedThreadPool(4);

        for (String url : hostList) {
            CallableImpl callable = new CallableImpl(url);
            callList.add(callable);
        }
        for (CallableImpl callableImpl : callList) {
            System.out.println("Trying to connect to: " + callableImpl.getUrl());
            Future<String> lol = es.submit(callableImpl);
            System.out.println("status: " + lol.get());
        }

        es.shutdown();

    }
}
公共类顺序pinger{
公共静态void main(字符串args[])引发异常{
字符串[]主机列表={”http://crunchify.com", "http://yahoo.com",
"http://www.ebay.com", "http://google.com",
"http://www.example.co", "https://paypal.com",
"http://bing.com/", "http://techcrunch.com/",
"http://mashable.com/", "http://thenextweb.com/",
"http://wordpress.com/", "http://cphbusiness.dk/",
"http://example.com/", "http://sjsu.edu/",
"http://ebay.co.uk/", "http://google.co.uk/",
"http://www.wikipedia.org/",
"http://dr.dk", "http://pol.dk", "https://www.google.dk",
"http://phoronix.com", "http://www.webupd8.org/",
"https://studypoint-plaul.rhcloud.com/", "http://stackoverflow.com",
"http://docs.oracle.com", "https://fronter.com",
"http://imgur.com/", "http://www.imagemagick.org"
};
List callList=new ArrayList();
Executors服务es=Executors.newFixedThreadPool(4);
用于(字符串url:hostList){
CallableImpl callable=新的CallableImpl(url);
callList.add(可调用);
}
for(CallableImpl CallableImpl:callList){
System.out.println(“正在尝试连接到:”+callableImpl.getUrl());
未来lol=es.submit(callableImpl);
System.out.println(“状态:+lol.get());
}
es.shutdown();
}
}
我的可调用实现

public class CallableImpl implements Callable<String> {

    private final String url;

    public CallableImpl(String url) {
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    @Override
    public String call() {
        String result = "Error";

        try {
            URL siteURL = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) siteURL
                    .openConnection();
            connection.setRequestMethod("GET");

            connection.connect();

            int code = connection.getResponseCode();
            if (code == 200) {
                result = "Green";
            }

            if (code == 301) {
                result = "Redirect";
            }

        } catch (IOException e) {
            result = "->Red<-";
        }
        return result;
    }
}
public类CallableImpl实现可调用{
私有最终字符串url;
公共CallableImpl(字符串url){
this.url=url;
}
公共字符串getUrl(){
返回url;
}
@凌驾
公共字符串调用(){
字符串result=“Error”;
试一试{
URL siteURL=新URL(URL);
HttpURLConnection连接=(HttpURLConnection)站点URL
.openConnection();
connection.setRequestMethod(“GET”);
connection.connect();
int code=connection.getResponseCode();
如果(代码==200){
结果=“绿色”;
}
如果(代码==301){
result=“重定向”;
}
}捕获(IOE异常){

结果=“->红色问题

创建后直接在
Future
上调用
get()
,阻塞主线程。因此根本没有任何并行调用,这使得
ExecutorService
基本上无用。您的代码相当于您自己简单地调用
callableImpl.call()

解决方案


如果要继续执行并使每个
CallableImpl
并行运行,请不要调用
get()
。相反,您可以在
es.shutdown()之后调用
es.awaitTermination()

创建后直接在
Future
上调用
get()
,阻塞主线程。因此根本没有任何并行调用,这使得
ExecutorService
基本上无用。您的代码相当于您自己简单地调用
callableImpl.call()

解决方案


如果您想继续执行并让每个
CallableImpl
并行运行,请不要调用
get()
。相反,您可以在
es.shutdown()
之后调用
es.waitTermination()
在您的代码中,将
Callable
提交给
ExecutorService
并立即调用
Future.get()
它将阻塞,直到结果就绪(或在运行时引发异常)

您最好将
ExecutorService
包装为
CompletionSerivce
,该服务在结果准备好后立即提供结果。并将for循环拆分为两个循环:一个用于提交所有
可调用的
s,另一个用于检查结果

ExecutorService es = Executors.newFixedThreadPool(4);
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(es);

for (CallableImpl callableImpl : callList) {
        System.out.println("Trying to connect to: " + callableImpl.getUrl());
        completionService.submit(callableImpl);
}
for (int i = 0; i < callList.size(); ++i) {
    completionService.take().get();   //fetch next finished Future and check its result
}
Executors服务=Executors.newFixedThreadPool(4);
ExecutorCompletionService completionService=新的ExecutorCompletionService;
for(CallableImpl CallableImpl:callList){
System.out.println(“正在尝试连接到:”+callableImpl.getUrl());
completionService.submit(callableImpl);
}
对于(int i=0;i
在代码中,您将
Callable
逐个提交给
ExecutorService
,并立即调用
Future.get()
,它将一直阻止,直到结果准备就绪(或在运行时引发异常)

您最好将
ExecutorService
包装为
CompletionSerivce
,该服务在结果准备好后立即提供结果。并将for循环拆分为两个循环:一个用于提交所有
可调用的
s,另一个用于检查结果

ExecutorService es = Executors.newFixedThreadPool(4);
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(es);

for (CallableImpl callableImpl : callList) {
        System.out.println("Trying to connect to: " + callableImpl.getUrl());
        completionService.submit(callableImpl);
}
for (int i = 0; i < callList.size(); ++i) {
    completionService.take().get();   //fetch next finished Future and check its result
}
Executors服务=Executors.newFixedThreadPool(4);
ExecutorCompletionService completionService=新的ExecutorCompletionService;
for(CallableImpl CallableImpl:callList){
System.out.println(“正在尝试连接到:”+callableImpl.getUrl());
completionService.submit(callableImpl);
}
对于(int i=0;i
我建议使用Java8中添加的,并向其添加回调

CompletableFuture.supplyAsync(myCallable::call, es)
        .thenAccept(result -> {
            something(result);
        });
我建议让你的电话成为一个供应商,这样做更简单。

我建议使用Java 8中添加的,并添加一个电话