2012-02-23 25 views
5

Cách tốt nhất để xử lý RejectedExecutionException trong khi sử dụng ThreadPoolExecutor trong Java là gì?Làm thế nào để xử lý RejectedExecutionException với ThreadPoolExecutor trong java

Tôi muốn đảm bảo rằng tác vụ được gửi không nên bỏ qua và chắc chắn sẽ được thực hiện. Hiện tại không có yêu cầu thời gian thực khó để hoàn thành nhiệm vụ.

Một trong những điều tôi nghĩ có thể được thực hiện là chờ đợi trong một vòng lặp cho đến khi tôi biết rằng có không gian trong hàng đợi runnable, và sau đó đi vào và thêm nó vào hàng đợi.

Sẽ rất vui nếu mọi người có thể chia sẻ trải nghiệm của họ.

Thêm giải pháp khả thi Tôi mặc dù:

while(executor.getQueue().remainingCapacity <= 0){ 
// keep looping 
Thread.sleep(100); 
}; 
//if the loop exits ,indicates that we have space in the queue hence 
//go ahead and add to the queue 
executor.execute(new ThreadInstance(params)); 
+0

Điều này sẽ tạo điều kiện cho cuộc đua nếu có nhiều hơn một chuỗi đang cố thực hiện điều này. Nó cũng sẽ ghi một cpu có thể có nghĩa là phải mất nhiều thời gian hơn để người thực thi xóa hàng đợi. ví dụ. nếu chỉ có một CPU cho trình bổ sung và trình thực thi, điều này có thể là thảm họa. –

+0

Từ kiến ​​trúc sẽ chỉ có một chủ đề làm điều này, và để xử lý thời gian CPU ăn, tôi đang làm cho giấc ngủ thread.How hiện này nhìn bây giờ? – Neeraj

+0

Ngủ, ngay cả trong một thời gian ngắn (thậm chí 1 - 10 ms) là tốt hơn nhiều so với không. 100 ms cũng là một giá trị tốt. Điều này là tốt nếu bạn chỉ có một chủ đề xuất bản. –

Trả lời

3

Tôi sẽ thay đổi hành vi của hàng đợi của bạn. ví dụ.

public class MyBlockingQueue<E> extends ArrayBlockingQueue<E> { 
    private final long timeoutMS; 

    public MyBlockingQueue(int capacity, long timeoutMS) { 
     super(capacity); 
     this.timeoutMS = timeoutMS; 
    } 

    @Override 
    public boolean offer(E e) { 
     try { 
      return super.offer(e, timeoutMS, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e1) { 
      Thread.currentThread().interrupt(); 
      return false; 
     } 
    } 
} 

Điều này sẽ chờ hàng đợi thoát ra trước khi bỏ cuộc.

+0

Tôi chỉ đơn giản là làm điều gì đó giống như while (executor.getQueue(). RemainingCapacity <= 0) {// keep looping}; // nếu vòng lặp thoát, chỉ ra rằng chúng ta có khoảng trống trong hàng đợi do đó // tiếp tục và thêm vào hàng đợi executor.execute (new ThreadInstance (params)); Điều này có vẻ là một giải pháp mà không cần phải tạo ra ví dụ của riêng tôi về ArrayBlockingQueue. – Neeraj

+0

bị lỗi thêm mã trong câu hỏi của tôi. Có vẻ như đã tắt. – Neeraj

+1

Bạn có điều kiện chủng tộc nếu bạn làm vậy. Không có gì đảm bảo rằng một luồng khác có thể không lấp đầy hàng đợi đang cố làm điều tương tự. Bạn không cần phải tạo ra ArrayBlockingQueue của riêng bạn, bạn có thể sao chép của tôi. ;) –

2

Nếu bạn đã hạn chế hồ bơi thread của bạn để chỉ cho phép một số lượng nhất định của chủ đề đồng thời (thường là một điều tốt), sau đó ứng dụng cần bằng cách nào đó push- trở lại trên mã gọi, vì vậy khi bạn nhận được một RejectedExecutionException từ ThreadPoolExecutor bạn cần phải chỉ ra điều này cho người gọi và người gọi sẽ cần phải xử lý thử lại.

Tình huống tương tự là máy chủ web chịu tải nặng. Một khách hàng kết nối, máy chủ web phải trả lại 503 - Dịch vụ không có sẵn (thường là tình trạng tạm thời) và khách hàng quyết định phải làm gì với nó.

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