多线程java优化
在我的程序中,我试图掌握如何使用ExecutorService优化我的程序。 由于某些原因,它在两个URL上有点卡住了。和。当它位于这两个URL上时,它不会继续执行其他URL 即使这两个域的响应速度不够快,其他3个可用线程是否也不能继续 如何以最好的方式解决这个问题多线程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
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中添加的,并添加一个电话