您的位置:首页 > 编程语言 > Java开发

JAVA处理线程超时

2013-12-24 18:57 375 查看
在实际业务中,由其是多线程并开业务中,经常会遇到某个线程执行超时。而程序如果不捕获这类情况,就会导致程序一直处于等待状态,从而影响后续线程的运行。

比如说网络通迅、单任务下的复杂数据库查询等,通常处理这类问题,可以启用一个后台守护线程来监控用户线程(业务线程)的执行是否超时,如果超时就不在等待,这种做法,通常是在调用用户线程的.start()方法之前,调用守护线程的start()方法,同时将超时时长传给守护线程。在守护线程的run()方法,执行sleep()方法,休眠时间为超时时长,守护线程中有一个同步后的变量用于存储用户线程是否超时。而在用户线程中,在程序执行完之后,再调用守掮线程改变同步变量。当守护线程sleep()方法之后,去有判断同步变量的值是否已改变,如果没有改变,说明用户线程还未扫行完毕,也就是超时。但这种方法,不能中断用户线程。

除此之外,还有一种方法,可以中断用户线程不在继续运行,采用java.util.concurrent下面的接口、类也可以完成。以下是例子。

Java代码


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 TimeOut {
public static void main(String[] args){
int timeout = 2; //秒.
ExecutorService executor = Executors.newSingleThreadExecutor();
Boolean result = false;
Future<Boolean> future = executor.submit(new MyJob("请求参数"));// 将任务提交到线程池中
try {
result = future.get(timeout*1000, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
System.out.println(result);
} catch (InterruptedException e) {
System.out.println("线程中断出错。");
future.cancel(true);// 中断执行此任务的线程
} catch (ExecutionException e) {
System.out.println("线程服务出错。");
future.cancel(true);// 中断执行此任务的线程
} catch (TimeoutException e) {// 超时异常
System.out.println("超时。");
future.cancel(true);// 中断执行此任务的线程
}finally{
System.out.println("线程服务关闭。");
executor.shutdown();
}
}

static class MyJob implements Callable<Boolean> {
private String t;
public MyJob(String temp){
this.t= temp;
}
public Boolean call() {
for(int i=0;i<999999999;i++){
if(i==999999997){
System.out.println(t);
}
if (Thread.interrupted()){ //很重要
return false;
}
}
System.out.println("继续执行..........");
return true;
}
}
}

在做socket通信时我这边服务端需要设置超时程序(客户端为硬件终端连接,没有回应几分钟内设置超时程序)

此socket服务端启动使用timertask类型,启动后再开几十个线程来处理终端连接。。。

我试了两种超时程序都蛮好:一种是通过线程的join设置,一种是通过concurrent的Future手段

join:

public class ThreadTest {

public static void main(String[] args) {

CounterThread ct = new CounterThread();

ct.start();

try {

ct.join(20000); //超时的时间,如20秒

if(ct.isAlive()){//说明再设定的时间内没有执行完,超时

ct.interrupt();

throw new TimeoutException();//抛出,让socket线程终止

}

ct.getResult();//正常情况下可以获取执行后的值

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

class CounterThread extends Thread {

public CounterThread(int time) {

构造函数,传递一些有用的值给run;

}

private int result;

public int getResult() {//在上面获取的结果值

return result;

}

public void run() {

result = 执行的任务,如读取客户端数据;

}

}

Furture:

public class TimeoutTest1 {

public static void main(String[] args) {

final ExecutorService service = Executors.newFixedThreadPool(1);

TaskThread taskThread = new TaskThread();

System.out.println("提交任务...begin");

Future<Object> taskFuture = service.submit(taskThread);

System.out.println("提交任务...end");

try {

Object re = taskFuture.get(6000, TimeUnit.MILLISECONDS);//超时设置,6s

System.out.println(re);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

} catch (TimeoutException e) {

System.out.println("超时 取消任务");

taskFuture.cancel(true);

System.out.println("超时 取消任务OK");

} finally {

service.shutdown();

}

}

}

class TaskThread implements Callable<Object> {

public Object call() throws Exception {

String result = "空结果";

try {

System.out.println("任务开始....");

Thread.sleep(5000);

result = "正确结果";

System.out.println("任务结束....");

} catch (Exception e) {

System.out.println("Task is interrupted!");

}

return result;

}

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