笔者在平常的项目开发中,会遇到有些程序执行时间过长的问题(比如查询数据库的时间过长,或者调用某一接口执行的时间过长),导致程序长时间卡死,因此,需要对程序进行超时中断处理,给程序的执行时间设定一个时间范围限制,如果超过这一范围,则进行中断处理,包括中断线程并且返回超时的结果。有时候线程已经在执行了,是无法中断的,程序要返回超时的结果,只是线程会继续执行,直到线程执行完成。

下面将介绍两种超时中断处理的实现方法,方法一是本人自己利用线程实现的,方法二则利用JDK自带的工具类FutureTask。

1、方法一

import java.util.Date;

public class TaskThread extends Thread {

private Task task;

public TaskThread(Task task) {

this.task = task;

}

public void run() {

int i = 0;

while(true && i < 10){

if(Task.STATUS_INTERRUPT.equals(task.getStatus())){

System.out.println(“线程执行中断”);

break;

}

System.out.println(new Date().toLocaleString()+”:每隔1秒打印一下日志”);

try {

Thread.sleep(1*1000);

i++;

} catch (InterruptedException e) {

e.printStackTrace();

}

}

task.setStatus(Task.STATUS_FINISHED);

System.out.println(“线程执行完成”);

}

}

import java.util.Date;

public class Task {

public static final String STATUS_START = “START”;

public static final String STATUS_FINISHED = “FINISHED”;

public static final String STATUS_INTERRUPT = “INTERRUPT”;

private String status = “”;

private Date startTime = null;

private TaskThread taskThread = null;

public void setStatus(String status) {

this.status = status;

}

public String execute() {

this.setStatus(Task.STATUS_START);

startTime = new Date();

taskThread = new TaskThread(this);

try{

taskThread.start();

}catch (Exception e) {

e.printStackTrace();

}

String result = “”;

while(true){

if(Task.STATUS_FINISHED.equals(this.getStatus())){

result = “任务执行成功”;

break;

}

Date currentTime = new Date();

if((currentTime.getTime() – this.getStartTime().getTime()) > 5*1000){

this.setStatus(Task.STATUS_INTERRUPT);

result = “任务执行中断”;

System.out.println(“线程执行超时:限定时间是5秒!”);

break;

}

}

return result;

}

public String getStatus() {

return status;

}

public Date getStartTime() {

return startTime;

}

public void setStartTime(Date startTime) {

this.startTime = startTime;

}

}

/**

* 当任务执行超时或者执行过程出现错误时,实现任务中断功能。

* @author brushli

* @date 2013-10-05

*

*/

public class InterruptExample {

public static void main(String[] args) {

Task task = new Task();

String execute = task.execute();

System.out.println(“result=”+execute);

}

}

程序执行的结果:

2013-10-5 15:10:45:每隔1秒打印一下日志

2013-10-5 15:10:46:每隔1秒打印一下日志

2013-10-5 15:10:47:每隔1秒打印一下日志

2013-10-5 15:10:48:每隔1秒打印一下日志

2013-10-5 15:10:49:每隔1秒打印一下日志

线程执行超时:限定时间是5秒!

result=任务执行中断

线程执行中断

线程执行完成

更改一下类Task中的代码,将超时的时间范围设定为50秒

if((currentTime.getTime() – this.getStartTime().getTime()) > 50*1000){

this.setStatus(Task.STATUS_INTERRUPT);

result = “任务执行中断”;

System.out.println(“线程执行超时:限定时间是50秒!”);

break;

}

此时程序的执行结果是:

2013-10-5 15:12:11:每隔1秒打印一下日志

2013-10-5 15:12:12:每隔1秒打印一下日志

2013-10-5 15:12:13:每隔1秒打印一下日志

2013-10-5 15:12:14:每隔1秒打印一下日志

2013-10-5 15:12:15:每隔1秒打印一下日志

2013-10-5 15:12:16:每隔1秒打印一下日志

2013-10-5 15:12:17:每隔1秒打印一下日志

2013-10-5 15:12:18:每隔1秒打印一下日志

2013-10-5 15:12:19:每隔1秒打印一下日志

2013-10-5 15:12:20:每隔1秒打印一下日志

线程执行完成

result=任务执行成功

2、方法二

利用JDK自带的工具类:FutureTask

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.FutureTask;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.TimeoutException;

/**

* 当任务执行超时或者执行过程出现错误时,实现任务中断功能。

* @author brushli

* @date 2013-10-05

*

*/

public class InterruptTest {

public static void main(String[] args) {

System.out.println(“result=”+new InterruptTest().getResult());

}

public String getResult() {

ExecutorService executorService = Executors.newSingleThreadExecutor();

FutureTask future = new FutureTask(new Callable() {

public String call() throws Exception {

InterruptTest interrupt = new InterruptTest();

return interrupt.getValue();

}

});

executorService.execute(future);

String result = null;

try{

//设定超时的时间范围为10秒

result = future.get(10, TimeUnit.SECONDS);

}catch (InterruptedException e) {

future.cancel(true);

System.out.println(“方法执行中断”);

}catch (ExecutionException e) {

future.cancel(true);

System.out.println(“Excution异常”);

}catch (TimeoutException e) {

future.cancel(true);

result = “方法执行时间超时”;

}

executorService.shutdownNow();

return result;

}

public String getValue()

{

try{

Thread.sleep(5000);

System.out.println(“正常执行”);

}catch (Exception e) {

e.printStackTrace();

}

return “正常结果”;

}

}

程序运行的结果是:

正常执行

result=正常结果

修改一下超时的时间:

//设定超时的时间范围为3秒

result = future.get(3, TimeUnit.SECONDS);

程序运行的结果是:

java.lang.InterruptedException: sleep interruptedresult=方法执行时间超时

at java.lang.Thread.sleep(Native Method)

at com.interrupt.InterruptTest.getValue(InterruptTest.java:48)

at com.interrupt.InterruptTest$1.call(InterruptTest.java:23)

at com.interrupt.InterruptTest$1.call(InterruptTest.java:1)

at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

at java.util.concurrent.FutureTask.run(FutureTask.java:138)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

at java.lang.Thread.run(Thread.java:662)


版权声明:本文为weixin_42133918原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_42133918/article/details/114393958