2011-01-27 33 views
11

Tôi có một ExecutorService quản lý một số cuộc gọi. Các nhiệm vụ mà chạy Callables chủ yếu là hộp đen biến đổi và số crunching. Trong điều kiện nhất định, dữ liệu được chuyển đổi sẽ dao động và luồng sẽ mất hơn một giờ để hoàn thành. Để so sánh, hầu hết các chủ đề được hoàn thành trong vòng một phút.Giới hạn thời gian đối với từng chủ đề với ExecutorService

Nó được xác định rằng dữ liệu từ các chuỗi dài chạy không liên quan. Tôi muốn làm gián đoạn bất kỳ chuỗi nào chạy lâu hơn một khoảng thời gian nhất định. Cách tốt nhất để làm điều này là gì?

Trả lời

19

Sử dụng ScheduleExecutorService để lên lịch nhiệm vụ cho taskFuture.cancel(true) tác vụ chạy dài khi đạt đến thời gian chờ. Nếu tác vụ kết thúc trước đó thì tác vụ sẽ không bị hủy.

ExecutorService service = Executors.newFixedThreadPool(N); 
ScheduledExecutorService canceller = Executors.newSingleThreadScheduledExecutor(); 

public <T> Future<T> executeTask(Callable<T> c, long timeoutMS){ 
    final Future<T> future = service.submit(c); 
    canceller.schedule(new Callable<Void>(){ 
     public Void call(){ 
      future.cancel(true); 
      return null; 
     } 
    }, timeoutMS, TimeUnit.MILLI_SECONDS); 
    return future; 
} 
3

Cách tốt nhất để bạn làm điều này là giới thiệu thêm một Executor. Bạn có thể sử dụng một ScheduledExecutorService để hủy bỏ tất cả các nhiệm vụ chạy dài ví dụ:

ExecutorService service = Executors.newFixedThreadPool(N); 

ScheduledExecutorService canceller = Executors.newScheduledThreadPool(1); 

public void executeTask(Callable<?> c){ 
    final Future<?> future = service.submit(c); 
    canceller.schedule(new Runnable(){ 
     public void run(){ 
      future.cancel(true); 
     } 
    }, SECONDS_UNTIL_TIMEOUT, TimeUnit.SECONDS); 
} 
+0

Cuộc gọi cần trả lại giá trị. –

+1

Cảm ơn, bạn có thể tưởng tượng tôi chỉ viết một tay miễn phí. Nếu chỉ Firefox có trình biên dịch được cài sẵn :) –

0

Bạn có thể nhận được một danh sách các Futures tương ứng của bạn (được tạo ra khi bạn gửi một Callable) cùng với thời gian khởi động của nó.

Một tác vụ khác sau đó có thể kiểm tra từng phút nếu có một số tác vụ đang chạy trong thời gian được xác định và nếu có, hãy gọi hủy (đúng) trong tương lai. Thực hiện tương lai sẽ bị xóa khỏi danh sách.

0

Bạn có thể sử dụng phương pháp này

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, 
           long timeout, 
           TimeUnit unit) 
          throws InterruptedException 

và thiết lập thời gian chờ tối đa cho một phút. Nếu chủ đề của bạn mất nhiều hơn nó chỉ bị hủy bỏ.

5

Bạn có thể hủy tương lai vv như trong các câu trả lời khác, nhưng bạn cần đảm bảo rằng chuỗi của bạn là "số crunching" có thể xử lý ngắt và chấm dứt duyên dáng. Bạn nói rằng đây là một hoạt động hộp đen - làm thế nào nhất định là bạn rằng tình trạng bị gián đoạn của thread đang được kiểm tra tích cực trong hộp đen? Nếu không, bạn không thể hủy nó bằng ngắt. Hộp đen cần phải được viết với sự gián đoạn trong tâm trí.

+0

+1 để chỉ ra rằng tác vụ có thể yêu cầu một số thông minh. – Raedwald

Các vấn đề liên quan