多线程执行超时处理:
package util; 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.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * 在某些情况下需要控制方法的运行时间,通过Thread+Callable+FutureTask完成 * Thread用于新开线程运行指定方法,Callable和FutrueTask用于监控方法运行时间。 * 启动一个任务,然后等待任务的计算结果,如果等待时间超出预设定的超时时间,则中止任务。 * * @author Cheng */ public class TimeoutUtil{ public static boolean checkTask(int timeout,Callable<Boolean> task) { ExecutorService exec = Executors.newCachedThreadPool(); Boolean taskResult = false; String failReason = null; Future<Boolean> future = exec.submit(task); try { // 等待计算结果,最长等待timeout秒(在第timeout秒取结果),timeout秒后中止任务 taskResult = future.get(timeout, TimeUnit.SECONDS); } catch (InterruptedException e) { failReason = "主线程在等待计算结果时被中断!"; } catch (ExecutionException e) { failReason = "主线程等待计算结果,但计算抛出异常!"; } catch (TimeoutException e) { failReason = "主线程等待计算结果超时,因此中断任务线程!"; exec.shutdownNow(); }finally{ exec.shutdown(); } return taskResult; } //测试 public static void main(String[] args) { Boolean flag=null; System.out.println("Start ..."); flag=TimeoutUtil.checkTask(15,new MyTask()); // 任务成功结束后等待计算结果,不需要等到15秒 System.out.println("\n执行结果:"+flag); System.out.println("\nStart ..."); flag=TimeoutUtil.checkTask(5,new MyTask()); // 只等待5秒,任务还没结束,所以将任务中止 System.out.println("\n执行结果:"+flag); } } class MyTask implements Callable<Boolean> { @Override public Boolean call() throws Exception { // 总计耗时约10秒 for (int i = 0; i < 100L; i++) { Thread.sleep(100); // 睡眠0.1秒 System.out.print('-'); if (Thread.interrupted()){ //很重要 return false; } } return Boolean.TRUE; } }输出信息:
Start ...
----------------------------------------------------------------------------------------------------
执行结果:true
Start ...
-------------------------------------------------
执行结果:false
Process finished with exit code 0
/** * 开启监控程序,远程脚本类似守护进程,不停止不返回 * @param req * @param resp * @return * @throws Exception */ @RequestMapping(value = "monitor.do",method=RequestMethod.GET) @ResponseBody public Map<String, Object> monitor(HttpServletRequest req, HttpServletResponse resp) throws Exception { System.out.println("monitor.do............."); ScpClient scp=new ScpClient("192.168.1.110",22,"root","123456"); //匿名类方式 /*Boolean flag=TimeoutUtil.checkTask(15, new Callable<Boolean>() { @Override public Boolean call() throws Exception { System.out.println("开始执行远程节点脚本...."); String rs=scp.exe("sh /root/Storm_shell/flume.sh"); System.out.println("远程节点脚本执行结束!"); return Boolean.TRUE; } });*/ //lambda表达式 Boolean flag=TimeoutUtil.checkTask(15, ()-> { System.out.println("开始执行远程节点脚本...."); String rs=scp.exe("sh /root/Storm_shell/flume.sh"); System.out.println("远程节点脚本执行结束!"); return Boolean.TRUE; }); System.out.println("15秒时间到!"); if(flag){ System.out.println("true"); }else{ System.out.println("false"); } scp.close(); Map<String, Object> map=new HashMap<String, Object>(); map.put("ok","程序正在执行..."); return map; }