并发包之Future:代码级控制超时时间
先谢Doug Lea。
使用场景:
最近在做webservice调用的时候,发现一个问题,对方的webservice接口很不稳定,所以在获取的数据时候经常要等待很久才能把数据全部拉回来,甚至有时候直接就抛异常了,这种阻塞很耗费时间,性能很低。针对这种情况,我需要将一定时间内没有返回结果的调用KILL掉,于是用到了并发包Future,实现并在生产环境运行良好。
============================================================
2015-07-13修改备注:
1、之前的代码存在executor没有关闭的异常;
2、对新来的朋友提个建议,频繁创建single线程池不是一个好建议。我之前的场景并发很低,看不出问题。随着现在接触的业务并发变得很大,根本不会这么写了,因为频繁的创建关闭线程会浪费很多资源。并发很小的情况,并且必须要控制超时时间的情况下可以试试。
很抱歉,本人阅历有限,希望没对读者造成影响。
============================================================
测试代码如下,自行体会:
package com.array7.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class FutureTest { public static void main(String[] args) { String result = ControlTimeOut.call(new CallableImpl("OK")); System.out.println(result); result = ControlTimeOut.call(new CallableImpl("NO OK!")); System.out.println("result=" + result); } } class ControlTimeOut { @SuppressWarnings("unchecked") public static <T> T call(Callable<T> callable) { ExecutorService executor = Executors.newCachedThreadPool(); Future<T> future = executor.submit(callable); try { T t = future.get(3000, TimeUnit.MILLISECONDS); executor.shutdwon(); return t; } catch (InterruptedException e) { System.out.println("InterruptedException"); } catch (ExecutionException e) { System.out.println("ExecutionException"); } catch (TimeoutException e) { // TODO: coding here... System.out.println("TimeoutException"); } return null; } } class CallableImpl implements Callable<String> { private static final String CORRECT_KEY = "OK"; private String key = ""; public CallableImpl(String key) { this.key = key; } public String call() { // TODO:真正的业务逻辑 if (CORRECT_KEY.equals(this.getKey())) { return "SUCCESS"; } else { try { Thread.sleep(5000); // 阻塞。设置5秒超时,为了Future抛出TimeoutException } catch (InterruptedException e) { e.printStackTrace(); } return "FAIL"; } } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
版权声明:本文为博主原创文章,未经博主允许不得转载。