您的位置:首页 > 其它

多线程执行超时处理

2017-01-22 11:03 323 查看
多线程执行超时处理:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: