2012-01-24 42 views
5

Trong một lớp java, tôi có một phương thức mà đôi khi mất nhiều thời gian để thực thi. Có lẽ nó treo trong luồng phương pháp đó. Những gì tôi muốn là nếu phương pháp không hoàn thành trong thời gian cụ thể, chương trình nên thoát khỏi phương pháp đó và tiếp tục với phần còn lại của dòng chảy.Phương pháp hết thời gian trong java

Vui lòng cho tôi biết là có cách nào để xử lý tình huống này.

Trả lời

7

Bạn phải sử dụng đề tài để đạt được điều này. Chủ đề không có hại :) Ví dụ dưới đây chạy một đoạn mã trong 10 giây và sau đó kết thúc nó.

public class Test { 
    public static void main(String args[]) 
     throws InterruptedException { 

     Thread thread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("0"); 
       method(); 
      } 
     }); 
     thread.start(); 
     long endTimeMillis = System.currentTimeMillis() + 10000; 
     while (thread.isAlive()) { 
      if (System.currentTimeMillis() > endTimeMillis) { 
       System.out.println("1"); 
       break; 
      } 
      try { 
       System.out.println("2"); 
       Thread.sleep(500); 
      } 
      catch (InterruptedException t) {} 
     } 


    } 

    static void method() { 
     long endTimeMillis = System.currentTimeMillis() + 10000; 
     while (true) { 
      // method logic 
      System.out.println("3"); 
      if (System.currentTimeMillis() > endTimeMillis) { 
       // do some clean-up 
       System.out.println("4"); 
       return; 
      } 
     } 
    } 
} 
+0

Tuyệt vời! Làm việc hoàn hảo cho tôi. – Haych

1

Thực thi phương thức theo một chủ đề khác, bạn có thể kết thúc một chuỗi bất kỳ lúc nào.

+0

Có cách nào bằng cách sử dụng Threads.I không muốn sử dụng Chủ đề. – Ran

+0

@Rana _Tôi không muốn sử dụng Threads_ Tại sao? Nếu bạn không quen thuộc, hãy xem [java tutorial] (http://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html) – COD3BOY

+0

Hi Sanjay, vấn đề với chủ đề là chúng ta không chắc chắn về việc thực hiện luồng luồng nếu chúng ta có nhiều luồng chạy cho cùng một phần mã có vẻ phức tạp một chút để quản lý hoặc gỡ lỗi. – Ran

0

Dựa trên đoạn mã trên, tôi đã thử tạo một hạt mùa xuân được tôn vinh.

Người thi hành như vậy chạy số được giới hạn đã qua trong giới hạn thời gian chạyInMs. Nếu tác vụ kết thúc trong giới hạn thời gian của nó, người gọi sẽ tiếp tục bình thường khi thực thi.

Nếu limitedRuntimeTask thất bại trong việc kết thúc trong định nghĩa runtimeInMs, người gọi sẽ nhận việc thực hiện chủ đề trở lại. Nếu một timeBreachedTask được xác định, nó sẽ được thực thi trước khi trở về người gọi.

public class LimitedRuntimeExecutorImpl { 


public void runTaskInLessThanGivenMs(int runtimeInMs, final Callable limitedRuntimeTask, final Callable timeBreachedTask) { 
    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       LOGGER.info("Started limitedRuntimeTask"); 
       limitedRuntimeTask.call(); 
       LOGGER.info("Finished limitedRuntimeTask in time"); 
      } catch (Exception e) { 
       LOGGER.error("LimitedRuntimeTask exception", e); 
      } 
     } 
    }); 
    thread.start(); 

    long endTimeMillis = System.currentTimeMillis() + runtimeInMs; 

    while (thread.isAlive()) { 
     if (System.currentTimeMillis() > endTimeMillis) { 
      LOGGER.warn("LmitedRuntimeTask did not finish in time (" + runtimeInMs + ")ms. It will run in vain."); 
      if(timeBreachedTask != null){ 
       try { 
        LOGGER.info("Executing timeBreachedTask"); 
        timeBreachedTask.call(); 
        LOGGER.info("Finished timeBreachedTask"); 
       } catch (Exception e) { 
        LOGGER.error("timeBreachedTask exception", e); 
       } 
      } 
      return; 
     } 
     try { 
      Thread.sleep(10); 
     } 
     catch (InterruptedException t) {} 
    } 

} 

}

0

tôi cảm thấy cách tiếp cận trong câu trả lời được chấp nhận là một chút lỗi thời. Với Java8, nó có thể được thực hiện đơn giản hơn nhiều.

Này, bạn có một phương pháp

MyResult conjureResult(String param) throws MyException { ... } 

sau đó bạn có thể làm điều này (tiếp tục đọc, điều này chỉ là để cho thấy phương pháp này):

private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor(); 

MyResult conjureResultWithTimeout(String param, int timeoutMs) throws Exception { 
    Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param)); 
    return future.get(timeoutMs, TimeUnit.MILLISECONDS); 
}  

tất nhiên, ném ngoại lệ là xấu, đây là phiên bản mở rộng chính xác với xử lý lỗi thích hợp, nhưng tôi khuyên bạn nên kiểm tra cẩn thận, có thể bạn muốn thực hiện một số việc khác (ghi nhật ký, trả lại thời gian chờ trong kết quả mở rộng, v.v.):

private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor(); 

MyResult conjureResultWithTimeout(String param, int timeoutMs) throws MyException { 
    Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param)); 
    try { 
     return future.get(timeoutMs, TimeUnit.MILLISECONDS); 
    } catch (InterruptedException e) { 
     //something interrupted, probably your service is shutting down 
     Thread.currentThread().interrupt(); 
     throw new RuntimeException(e); 
    } catch (ExecutionException e) { 
     //error happened while executing conjureResult() - handle it 
     if (e.getCause() instanceof MyException) { 
      throw (MyException)e.getCause(); 
     } else { 
      throw new RuntimeException(e); 
     } 
    } catch (TimeoutException e) { 
     //timeout expired, you may want to do something else here 
     throw new RuntimeException(e); 
    } 
} 
Các vấn đề liên quan