最近在看多线程的一些东西,昨天有个接口调服务器上的有时候会报错(两台服务器都有报错的情况),但是本地试了好多次都没问题,一次次点击又比较烦,就参考了一些例子用ExecutorService开线程池请求本地接口测试。
写完之后感觉和之前的一个照猫画虎地例子很像http://blog.csdn.net/fasure_smile/article/details/52190042,又查了些资料,然后完全被Executor、Executors、ExecutorService、ThreadPoolExecutor等等搞懵逼了, 基础巨差的缺点又一次暴露出来了。
这几个类后面要再研究研究,现在先记录代码,把方法学会,后面再去探究其所以然。下面上代码。
--------------------------------------------------------------------------------------------------------------------------------------------------
package com.fasure.thread.ExecutorService;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExecutorServiceTest {
static final Integer MAX_THREAD=15;
static final Logger LOG=LoggerFactory.getLogger(ExecutorServiceTest.class);
public static ExecutorService EXCUTOR=Executors.newFixedThreadPool(MAX_THREAD);
//请求本地接口的一些参数
static String URL = "http://localhost:8080/api/account/alipay/validatereal";
static String PARAM_STR = "userid=ec9e7a8a4db4119d9208a40dc190b2bb5f6af08d940557&idcard=7cf15f97fad048e54ec3e5a5cac39a85&name=8e6a6acb5fd7&alipayOauthCode=a7406c37c23513d8b5f6af08d940557&cloudOauthToken=698e5bfa2ee222974b4d87fafceee275f42";
static String METHOD = "POST";
public static void executionHistorySatistics(){
try {
try {
excutorStatistics();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} catch (ParseException e) {
e.printStackTrace();
}
}
private static void excutorStatistics() throws ParseException, InterruptedException, ExecutionException {
List<Future<String>> list = new ArrayList<Future<String>>();
int in = 1;
for(int i = 0; i < 50; i++){
//HttpRequestUtil()实现Callable<?>接口,可以获取返回值Future<?>,并将其存到List中去
Future<String> future = EXCUTOR.submit(new HttpRequestUtil(i+1, URL, PARAM_STR, METHOD));
list.add(future);
}
Thread.sleep(10000);
for (Future<String> future : list) {
//从List中读取线程运程返回的结果,统计请求线程接口成功的次数
if(future.get().equals("200")){
System.out.println(future.get() + "---" + in);
in++;
}
}
EXCUTOR.shutdown();
}
public static void main(String[] args) {
//程序运行入口
executionHistorySatistics();
}
}
package com.fasure.thread.ExecutorService;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONObject;
public class HttpRequestUtil implements Callable<String>{
private int i;
private String url;
private String paramStr;
private String method;
public HttpRequestUtil(int i, String url, String paramStr, String method) {
super();
this.i = i;
this.url = url;
this.paramStr = paramStr;
this.method = method;
}
@Override
public String call() throws Exception {
JSONObject result = basicConnection(i, url, paramStr, method);
return result.getString("code");
}
public static JSONObject basicConnection(int i, String urlstr, String paramStr, String method) {
String result = null;
HttpURLConnection connection = null;
URL url = null;
JSONObject data = new JSONObject();
try {
url = new URL(urlstr + "?" + paramStr);
System.out.println("\n请求url:::" + urlstr + "?" + paramStr);
System.out.println(i);
connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestMethod(method);
BufferedReader br = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "UTF-8"));
StringBuffer buffer = new StringBuffer();
String temp = null;
while ((temp = br.readLine()) != null) {
buffer.append(temp);
}
result = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isNotBlank(result)) {
data = JSONObject.parseObject(result);
} else {
data.put("code", "400");
data.put("success", false);
data.put("msg", "获取数据失败");
}
return data;
}
}
参考链接:
http://www.cnblogs.com/wanqieddy/p/3853863.html
http://blog.csdn.net/linghu_java/article/details/17123057
关于第一篇里面介绍的ExecutorService的submit与execute的差别,我看了一下觉得有点乱。实际测试,看了源码后得到一些简单结论,如下:
1、Executor为ExecutorService的父类(public interface ExecutorService extends Executor);
2、execute为Executor中的方法,且ExecutorService未做复写;
3、ExecutorService中重载了三个submit方法:<T> Future<T> submit(Callable<T> task)、<T> Future<T> submit(Runnable task, T result)、Future<?> submit(Runnable task);
4、Callable接口类似Runnable接口,对应的二者中的方法分别为call()和run(),不同的是call()有返回值,而run()为void;
大概就这些了,具体的话可以运行一下项目,点进这些类中看一下就明白了。