2013-05-14 23 views
7

Tôi đang viết một ứng dụng bằng Java sử dụng ExecutorService để chạy nhiều luồng.Theo dõi các tác vụ đã hoàn thành trong ExecutorService

Tôi muốn gửi nhiều tác vụ (hàng nghìn lần một lần) cho Người thi hành dưới dạng Cuộc gọi và khi hoàn tất, hãy truy xuất kết quả của họ. Cách tôi tiếp cận điều này là mỗi khi tôi gọi hàm submit(), tôi nhận được một tương lai mà tôi lưu trữ trong một ArrayList. Sau đó, tôi chuyển Danh sách tới một chuỗi liên tục lặp lại nó, gọi hàm future.get() với thời gian chờ để xem tác vụ đã hoàn thành chưa. đây có phải là cách tiếp cận đúng hay là quá kém hiệu quả?

CHỈNH SỬA --- Thông tin thêm --- Một vấn đề khác là mỗi Cuộc gọi có thời gian xử lý khác nhau. Vì vậy, nếu tôi chỉ cần lấy phần tử đầu tiên ra khỏi Danh sách và gọi get() vào nó, nó sẽ chặn trong khi kết quả của những người khác có thể trở nên có sẵn và chương trình sẽ không biết. Đó là lý do tại sao tôi cần phải tiếp tục lặp lại với thời gian chờ.

cảm ơn trước

+0

tôi khuyên bạn nên xem xét các tiện ích ListenableFuture trong thư viện Ổi: https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained – Enwired

Trả lời

1

Lưu ý rằng cuộc gọi đến Future.get sẽ chặn cho đến khi câu trả lời khả dụng. Vì vậy, bạn không cần một luồng khác để lặp qua danh sách mảng.

Xem ở đây https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6

+0

Hiểu. Nhưng tôi gửi hàng ngàn nhiệm vụ cho ExecutorService trong burst. Vì vậy, tôi cần phải lưu trữ tương lai một nơi nào đó để tham khảo trong tương lai. Trong khi tôi bị chặn trên Cuộc gọi đầu tiên, một người khác có thể đã được hoàn thành và tôi sẽ không biết. Bất kỳ ý tưởng? –

+0

Lưu trữ chúng trong danh sách là tốt. Bạn sẽ nhận được một trong đó đã hoàn thành ngay sau khi một trong đó là bị chặn hoàn tất. – Woody

+0

Lưu trữ chúng trong danh sách là tốt. Bạn sẽ nhận được một trong đó đã hoàn thành ngay sau khi một trong đó là bị chặn hoàn tất. Nếu bạn cần được thông báo về mọi lần hoàn thành đơn lẻ và khi nó hoàn thành, ví dụ: để cập nhật giao diện người dùng nói chung, bạn nên sử dụng cơ chế thông báo thay vì bỏ phiếu. Tôi nghĩ Future.get là một cơ chế quá chung chung cho mục đích đó. – Woody

6

này là cách tiếp cận đúng hay là quá kém hiệu quả?

Đây không phải là cách tiếp cận chính xác. Bạn đang không cần thiết lặp lại trên ArrayList kiểm tra để hoàn thành nhiệm vụ.

Điều này rất đơn giản: Chỉ cần sử dụng: CompletionService. Bạn có thể dễ dàng bọc trình thực hiện hiện tại của bạn vào nó. Từ JavaDocs:

Nhà sản xuất gửi nhiệm vụ để thực thi. Người tiêu dùng hoàn thành nhiệm vụ và xử lý kết quả của họ theo thứ tự mà họ hoàn thành.

Về bản chất, CompletionService cung cấp cách lấy lại kết quả đơn giản bằng cách gọi take(). Nó là một chức năng chặn và người gọi sẽ chặn cho đến khi kết quả có sẵn.