http异步请求使用Apache提供的HttpAsyncClient
// final Map<String, String> mapTest = new HashMap<String, String>();
final RequestConfig requestConfitg = RequestConfig.custom().setSocketTimeout(30).setConnectTimeout(30).build();
final CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().setDefaultRequestConfig(requestConfitg).build();
httpclient.start();
HttpGet[] requests = new HttpGet[] {
new HttpGet("http://www.apache.org/"),
new HttpGet("https://www.verisign.com/"),
new HttpGet("http://www.google.com/"),
new HttpGet("http://www.baidu.com/")
// new HttpGet(""),
// new HttpGet("")
};
final CountDownLatch latch = new CountDownLatch(requests.length);
for (final HttpGet request: requests) {
httpclient.execute(request, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
latch.countDown();
// try {
// JSONObject testJsonObject = JSONObject.parseObject(EntityUtils.toString(response.getEntity(), "GBK"));
// String apiName = testJsonObject.getString("api");
// String apiData = testJsonObject.getString("data");
// mapTest.put(apiName, apiData);
// } catch (Exception e) {
// e.printStackTrace();
// }
System.out.println(request.getRequestLine() + "->" + response.getStatusLine());
}
public void failed(final Exception ex) {
latch.countDown();
ex.printStackTrace();
}
public void cancelled() {
latch.countDown();
}
});
}
// latch.await(100, TimeUnit.MILLISECONDS);
latch.await();
httpclient.close();
System.out.println("Done");
maven里添加依赖:httpasyncclient/httpcore-nio/httpcore/httpclient
----------------------------------------------
使用ExecutorService与Future实现异步多线程
final ExecutorService exec = Executors.newFixedThreadPool(5);
Future[] task_list = new Future[5];
for(int i = 1; i <= 3; ++i) {
System.out.println(i);
yibu.MyCallableClass task = new yibu.MyCallableClass(i);
// Callable call = new Callable(){
// public String call() throws Exception{
// System.out.println("------" + i);
// Thread.sleep(1000 * j);
// return "Other less important but longtime things.";
// }
// };
task_list[i] = exec.submit(task);
}
// System.out.println("Let's do important things.");
Thread.sleep(1000 * 1);
//重要的事情
System.out.println("Let's do important things.");
for(int i = 1; i <= 3; ++i) {
String obj = "nothing";
try {
obj = (String)task_list[i].get(0, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// System.out.println("----------------");
task_list[i].cancel(true);
}
System.out.println(obj);
}
System.out.println("Let's do final things.");
//关闭线程池
exec.shutdown();
public class yibu {
public static class MyCallableClass implements Callable{
private int flag = 0;
public MyCallableClass(int flag){
this.flag = flag;
}
public String call() throws Exception{
Thread.sleep(500 * this.flag);
String testUrl = "";
String final_string = "";
URL getUrl = new URL(testUrl);
HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String lines;
while ((lines = reader.readLine()) != null) {
// System.out.println(lines);
final_string = final_string + lines;
}
reader.close();
// 断开连接
connection.disconnect();
// return "-------" + this.flag;
return final_string;
}
}
}
使用future的get方法设置超时,会在主线程进行阻塞,而不是每个子线程的超时,最后如果用for循环来get最终的结果设置的超时可能会有问题,可以用一个很挫的方法,记录开始异步调用多线程时的时间,然后get时用系统时间减去之前的时间来设置超时。另外可以用CountDownLatch来确保所有子线程返回结果,见第一段代码。