最近在看多线程的一些东西,昨天有个接口调服务器上的有时候会报错(两台服务器都有报错的情况),但是本地试了好多次都没问题,一次次点击又比较烦,就参考了一些例子用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;
大概就这些了,具体的话可以运行一下项目,点进这些类中看一下就明白了。
代码下载:http://download.csdn.net/detail/fasure_smile/9699938