Java.util.concurrent 包 使用Future,Callable实现抢答模式
2016-05-11 12:32
573 查看
我一直认为,在工作中总结是很必要的。尤其是自己刚刚发现了新大陆。比如java.util.concurrent 包的使用,之前我只是知道 Thread,Runnable。决心成为java大牛的我,在知道了concurrent 包后,一直在了解和编写示例。但是我感觉只有在实际应用中,我才能更深刻的掌握,机会终于来了。
我负责处理这样一个请求,请求传递给我一个证件号,我需要去请求两个webservice接口,因为不清楚,这个证件号通过哪个webservice才能正确的得到我想要的结果。
我觉得应该这样去设计,同时去请求两个webserice,谁先返回正确结果,就使用这个结果,同时让另一个中止工作。如果两个都没有返回正确的结果,则为异常。好像两个人进行抢答一样,下面是我写的代码。
getFbtResult 方法中实现了我的思路。同时提交两个任务去查询信息,在while(true) 无限循环里,去等待结果,谁先返回正确的信息,就直接返回,同时取消另一任务,如果两个都返回错误结果或者异常了,就跳出循环,如果有一个返回错误结果或者异常,就不再进入判断。
同时,我用动态代理,统计了请求接口的时间。
我负责处理这样一个请求,请求传递给我一个证件号,我需要去请求两个webservice接口,因为不清楚,这个证件号通过哪个webservice才能正确的得到我想要的结果。
我觉得应该这样去设计,同时去请求两个webserice,谁先返回正确结果,就使用这个结果,同时让另一个中止工作。如果两个都没有返回正确的结果,则为异常。好像两个人进行抢答一样,下面是我写的代码。
/** * * */ public class FlightWebServiceInterface implements IFbtInvoking{ public static Logger logger = LoggerFactory.getLogger(); //工贸正式地址 public final static String url = "http://10.10.65.146:9080/pptpolicy/flightWS.ws"; /** * * @param idCardNumber 身份证号码 * @return format xml */ public String getXmlResultByNI(String idCardNumber) throws Exception{ try { logger.info("start method String getXmlResultByNI(String idCardNumber), arg idCardNumber:"+idCardNumber); // query airport message by idcard number String urlname = url; // new Service Service s = new Service(); // build a Call via the new service object Call call = (Call) s.createCall(); // set Timeout call.setTimeout(new Integer(30000)); // set the remote method what will to invoke call.setOperation("detrByNI"); // set the remote url address call.setTargetEndpointAddress(urlname); // set the arg need to transfer call.addParameter("CardID", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);// 接口的参数 call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型 logger.info("调用工贸接口 ,方法:detrByNI "+"参数 CardID :"+idCardNumber); String result = (String) call.invoke(new Object[] { idCardNumber }); // 给方法传递参数,并且调用方法 logger.info("调用正常:"+idCardNumber); return result; } catch (Exception e) { logger.info("调用工贸接口异常",e); throw e; } } /** * * @param CardID * 护照号码 * @return format xml */ public String getXmlResultByPP(String CardID) throws Exception{ try { // logger.info("start method String getXmlResultByPP(String CardID), arg CardID:"+CardID); // query airport message by passport number String urlname = url; // new Service Service s = new Service(); // build a Call via the new service object Call call = (Call) s.createCall(); // set Timeout call.setTimeout(new Integer(30000)); // set the remote method what will to invoke call.setOperation("detrByPP"); // set the remote url address call.setTargetEndpointAddress(urlname); // set the arg need to transfer call.addParameter("CardID", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);// 接口的参数 call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型 logger.info("调用工贸接口 ,方法:detrByPP "+"参数 CardID :"+CardID); String result = (String) call.invoke(new Object[] { CardID }); // 给方法传递参数,并且调用方法 logger.info("调用正常:"+CardID); return result; } catch (Exception e) { logger.info("调用工贸接口异常",e); throw e; } } class RemoteNITask implements Callable<String>{ private String id; public RemoteNITask(String id) { super(); this.id = id; } @Override public String call() throws Exception { String result = getXmlResultByNI(this.id); return result; } } class RemotePPTask implements Callable<String>{ private String id; public RemotePPTask(String id) { super(); this.id = id; } @Override public String call() throws Exception { String result = getXmlResultByPP(id); return result; } } /** * {@inheritDoc} */ @Override public String getFbtResult(String id) { ExecutorService service = Executors.newFixedThreadPool(2); Future<String> fn = service.submit(new RemoteNITask(id)); Future<String> fp = service.submit(new RemotePPTask(id)); service.shutdown(); boolean bn = false; boolean bp = false; boolean bbn = true; boolean bbp = true; while(true){ if(fn.isDone() && !fn.isCancelled() && bbn){ try { String result = fn.get(); logger.info("NI"+result); if(!result.equals("") && result.indexOf("E00000")<0){ fp.cancel(true); return result; }else{ bn = true; bbn= false; } } catch (Exception e){ bn = true; bbn = false; } } if(fp.isDone() && !fp.isCancelled() && bbp){ try { String result = fp.get(); logger.info("PP"+result); if(!result.equals("") && result.indexOf("E00000")<0){ fn.cancel(true); return result; }else{ bp = true; bbp = false; } } catch (Exception e) { bp = true; bbp = false; } } if(bn && bp){ return ""; } } } public static void main(String[] args) { IFbtInvoking o = (IFbtInvoking) FbtProxy.getInstance("Z2538370"); String result = o.getFbtResult("Z2538370"); System.out.println(result); } }
getFbtResult 方法中实现了我的思路。同时提交两个任务去查询信息,在while(true) 无限循环里,去等待结果,谁先返回正确的信息,就直接返回,同时取消另一任务,如果两个都返回错误结果或者异常了,就跳出循环,如果有一个返回错误结果或者异常,就不再进入判断。
同时,我用动态代理,统计了请求接口的时间。
public class FbtProxy implements InvocationHandler { public static Logger logger = LoggerFactory.getLogger(); private Object o; private String id; public FbtProxy(Object o,String id) { super(); this.o = o; this.id = id; } public static Object getInstance(String id){ IFbtInvoking origin = new FlightWebServiceInterface(); InvocationHandler handler = new FbtProxy(origin, id); Object o = Proxy.newProxyInstance(origin.getClass().getClassLoader(), origin.getClass().getInterfaces(), handler); return o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; long startTime=System.currentTimeMillis(); //获取开始时间 result = method.invoke(o, args); long endTime=System.currentTimeMillis(); //获取结束时间 System.out.println("证件号"+this.id+"调用运行时间: "+(endTime-startTime)+"ms"); logger.info("证件号"+this.id+"调用运行时间: "+(endTime-startTime)+"ms"); return result; } } 文章写的粗糙,只是想分享出来,希望高手可以教我如何更快,性能更好的处理方式。
相关文章推荐
- struts中json的使用
- JAVA SQL语句--登陆
- JAVA SQL语句---注册
- Java序列化与反序列化
- java二维码开发
- java 合并文件-分割文件
- Java 8方法引用使用指南
- Java 8方法引用使用指南
- java的重载、覆盖和隐藏的区别
- java 打印流
- java wait()和notify()、notifyAll()
- Spring框架
- spring基础部分——注解
- spring线程池ThreadPoolExecutor配置并且得到任务执行的结果
- java.lang.OutOfMemoryError: PermGen space
- Spring中的ThreadPoolTaskExecutor
- Spring MVC工作流程图
- 设置eclipse 黑色主题
- java注解(二)Annotation使用案例
- 实例解析Java设计模式编程中的适配器模式使用