一、函数式方法
import java.util.HashMap; import java.util.concurrent.*; import java.util.function.Supplier; /** * 设置一个方法运行超时时间,超时结束该方法 * 缺陷:线程池shutdown结束不了死循环。 */ public class TimeOutShutdownMethod { /** 超时时间 **/ private static final int TIMEOUT = 30; /** 超时时间单位 **/ private static final TimeUnit TIMEOUT_UNIT = TimeUnit.SECONDS; /** * 设置方法的超时时间 * @param increase 调用的方法 * @return 调用方法的return值 */ public static Object setMethodShutdownTimeOut(Supplier<Object> increase) { return setMethodShutdownTimeOut(increase, TIMEOUT, TIMEOUT_UNIT); } /** * 设置方法的超时时间 * @param increase 调用的方法 * @param timeout 超时时间 * @param timeUnit 超时时间单位 * @return 调用方法的return值 */ public static Object setMethodShutdownTimeOut(Supplier<Object> increase, int timeout, TimeUnit timeUnit) { final ExecutorService exec = Executors.newFixedThreadPool(1); Callable call = () -> increase.get(); Future<String> future = exec.submit(call); Object object = null; try { object = future.get(timeout, timeUnit); System.out.println("方法执行完成"); } catch (Exception e) { // 方法超时 System.out.println("方法执行失败"); } exec.shutdownNow(); return object; } public static void main(String[] args) { Supplier<Object> increase = () -> t("1", "2", 3); HashMap<String, Object> tt = (HashMap<String, Object>) setMethodShutdownTimeOut(increase, 5, TIMEOUT_UNIT); System.out.println(tt); } public static HashMap t(String a, String b, Integer c) { int aa = 1; while (true) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } if (aa ++ > 1) { break; } } HashMap<String, Object> stringStringHashMap = new HashMap<>(); stringStringHashMap.put(a, b); stringStringHashMap.put(b, c); return stringStringHashMap; } }
二、反射实现
import java.lang.reflect.Method; import java.util.HashMap; import java.util.concurrent.*; /** * 设置一个方法运行超时时间,超时结束该方法 * 缺陷:方法参数不能是基础类型(利用反射但未传类型参数,只传参数值。参数值toClass会转成包装类)。线程池shutdown结束不了死循环。 * */ public class TimeOutShutdownMethod { private static final Logger logger = Logger.getLogger("TimeOutShutdownMethod.class"); /** 超时时间 **/ private static final int TIMEOUT = 30; /** 超时时间单位 **/ private static final TimeUnit TIMEOUT_UNIT = TimeUnit.SECONDS; /** * 设置方法的超时时间 * @param clazz 调用的方法所属的类 * @param methodName 调用的方法 * @param args 调用的方法参数 * @return 调用方法的return值 */ public static Object setMethodShutdownTimeOut(Class clazz, String methodName, Object... args) { return setMethodTimeOut(clazz, methodName, TIMEOUT, TIMEOUT_UNIT, args); } /** * 设置方法的超时时间 * @param clazz 调用的方法所属的类 * @param methodName 调用的方法 * @param timeout 超时时间 * @param timeUnit 超时时间单位 * @param args 调用的方法参数 * @return 调用方法的return值 */ public static Object setMethodTimeOut(Class clazz, String methodName, int timeout, TimeUnit timeUnit, Object... args) { final ExecutorService exec = Executors.newFixedThreadPool(1); Callable call = () -> { Method method = clazz.getDeclaredMethod(methodName, toClass(args));
method.setAccessible(true); Object invoke = method.invoke(clazz.newInstance(), args); return invoke; }; Future<String> future = exec.submit(call); Object object = null; try { object = future.get(timeout, timeUnit); System.out.println("方法执行完成"); } catch (Exception e) { // 方法超时 System.out.println("方法执行失败"); logger.error("method exec timeout!!!", e); } // 结束不了死循环 exec.shutdownNow(); return object; } private static Class<?>[] toClass(Object... args) { Class<?>[] parameterTypes = new Class<?>[args.length]; for (int i=0; i < args.length; i++) { parameterTypes[i] = args[i].getClass(); } return parameterTypes; } public static void main(String[] args) { System.out.println("RRR: "); System.out.println(TimeOutShutdownMethod.setMethodTimeOut(TimeOutShutdownMethod.class, "t", 50, TimeUnit.SECONDS,"sr", "rr", 123)); } public static HashMap t(String a, String b, Integer c) { int aa = 1; while (true) { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } if (aa ++ > 10) { break; } } HashMap<String, Object> stringStringHashMap = new HashMap<>(); stringStringHashMap.put(a, b); stringStringHashMap.put(b, c); return stringStringHashMap; } }