【问题标题】:Timeout for a method方法超时
【发布时间】:2013-04-25 12:42:16
【问题描述】:

我的程序如下所示

  1. 主程序(线程 1)
  2. 创建多个简单的 java 线程(Thead 1.1、1.2...)
  3. 在每个线程(1.1 或 1.2..)中,我正在做一些处理,同时调用一种方法,即 有时没有响应(CORBA 调用)。我想为 此方法和线程(调用者为 1.1 或 1.2)应自行等待,直到我得到响应或计时器到期。

我编写了以下示例程序。我不认为这是正确的做法。有没有更好的方法?在这个 prg 中,我不确定何时调用中断方法。

public class MethodTimeout implements Runnable{

/**
 * @param args
 */

public Thread t1 = null;
public int threadnum = 0;
public static void main(String[] args) {


    for (int i=0; i<3; i++){
        MethodTimeout mt  =new MethodTimeout();
        Thread t = new Thread(mt,"thread "+(i+1));
        mt.t1 = t;
        mt.threadnum = (i+1); 
        t.start();
    }

    System.out.println("stmt after execution");
}

public Object testTimeout(){
    long startTime = System.currentTimeMillis();
    try {

        System.out.println("in side method start "+t1.getName()+" start time"+startTime);

        Thread.sleep(5000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long endtime = System.currentTimeMillis();
    System.out.println("in side method end "+t1.getName()+" total time"+(endtime-startTime) );
    return null;
}


@Override
public void run() {

    Thread timeout  = new Thread (){
        public void run() {
            testTimeout();
        };
    };
    timeout.start();

    try {
        Thread.sleep(2000);
        timeout.interrupt();
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
    System.out.println(t1.getName() + " is ending");
}

}

【问题讨论】:

标签: java multithreading timer


【解决方案1】:

这听起来很像你应该实现 Callable。 这只是一个例子

 import java.util.concurrent.Callable;
 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 Test {    
     public static void main(String[] args) throws Exception {
         ExecutorService service = Executors.newFixedThreadPool(2);
         Future<String> futureResult = service.submit(new MyCall());
             try{
                 String result = futureResult.get(20, TimeUnit.MILLISECONDS);
             } catch(TimeoutException timeout){
                  System.out.println("Timeout");
                  service.shutdownNow();
             }
   }

   static class MyCall implements Callable<String> {
        @Override
        public String call() throws Exception {
             try{
                  //Simulate some corba work
                  Thread.sleep(1000);
             }catch(InterruptedException e){
                  Thread.currentThread().interrupt();
                  System.out.println("Shutting down the task!");
             }
                 return "The result";
        }
    }
} 

【讨论】:

  • 我已经检查过这个 Callable 示例也试过了,但它只是提供了超时功能,但是如何停止我正在运行的线程直到它执行或计时器到期。
  • @learner “我的正在运行的线程”是什么意思?您是否希望主线程被阻塞,直到另一个线程在间隔内过期成功执行?如果是这样,那么这已经发生了。此调用:String result = futureResult.get(20, TimeUnit.MILLISECONDS); 是一个阻塞调用。执行它的线程将不会继续前进,直到:a)超时已经发生 b)在超时之前返回的方法
【解决方案2】:

您还可以对@Eugene 的答案进行一个小改动,即不用在ExecutorService 本身上调用shutdownNow(),您只需在超时的futureResult 上调用cancel(true)。这是代码sn-p:

public class Test {    
     public static void main(String[] args) throws Exception {
         ExecutorService service = Executors.newFixedThreadPool(2);
         Future<String> futureResult = service.submit(new MyCall());
             try{
                 String result = futureResult.get(20, TimeUnit.MILLISECONDS);
             } catch(TimeoutException timeout){
                  System.out.println("Timeout");
             } finally {
                  futureResult.cancel(true);
             }
   }

这只是为了确保只取消超时线程。因为shutdownNow() 除了尝试停止当前正在执行的任务之外,还阻止等待任务的启动。

【讨论】:

    猜你喜欢
    • 2013-05-12
    • 2010-12-20
    • 2018-05-21
    • 2012-01-20
    • 1970-01-01
    • 2016-02-25
    • 2015-05-25
    • 1970-01-01
    • 2013-09-01
    相关资源
    最近更新 更多