2012-09-20 52 views
8

thể trùng lặp:
Java Executors: how can I set task priority?đợi Sắp xếp lại trong ThreadPoolExecutor Java

Tôi có một ThreadPoolExecutor xây dựng sử dụng một LinkedBlockingDequeue và tôi muốn thao tác hàng đợi cơ bản, tuy nhiên đọc bài viết này trong tài liệu làm tôi rất lo lắng.

bảo trì Queue

Phương pháp getQueue() cho phép truy cập vào hàng đợi công việc cho các mục đích giám sát và gỡ lỗi. Sử dụng phương pháp này cho bất kỳ mục đích nào khác không được khuyến khích mạnh mẽ. Hai phương thức được cung cấp, loại bỏ (java.lang.Runnable) và purge() có sẵn để hỗ trợ trong việc phục hồi lưu trữ khi số lượng lớn các tác vụ xếp hàng bị hủy bỏ.

Cụ thể là tôi muốn để có thể

  1. Kiểm tra hàng đợi để xem nếu một phần tử đã tồn tại. Tôi cho rằng điều này là tốt vì không cần khóa nên chỉ cần xem các phần tử trong hàng đợi.
  2. Tôi muốn sắp xếp lại hàng đợi dựa trên một số tín hiệu. Điều này rõ ràng có thể là rắc rối. Tôi đã tự hỏi nếu có một cách ưa thích để làm điều này để tôi sẽ không mess lên hàng đợi cho sử dụng khác.

Cảm ơn

+0

Là ghi chú tài liệu, bạn không nên kiểm soát hàng đợi từ phương thức đó. Bạn nên kiểm soát nó từ hàng đợi mà bạn đã chuyển vào 'ThreadPoolExecutor' của bạn. – pickypg

+0

Nhưng điều đó vẫn không có nguy cơ gặp vấn đề về luồng không? Tôi nghĩ rằng nếu tôi gọi getQueue() đó là giống như sửa đổi các đối tượng hàng đợi thực tế tôi vượt qua trong. – Jon

+2

Tôi không nghĩ rằng tôi có thể sử dụng một PriorityComparator như được đề xuất trong câu hỏi khác bởi vì PriorityComparator không cung cấp cách nào để sắp xếp lại các phần tử khi chúng nằm trong hàng đợi. – Jon

Trả lời

4

getQueue() sẽ luôn trả lại chính xác BlockingQueue<Runnable> mà bạn vượt qua vào ThreadPoolExecutor.

Sự lo lắng với tài liệu là bạn có thể dễ dàng gặp phải các vấn đề với hoạt động kép nếu bạn không thể đảm bảo an toàn luồng của BlockingQueue. Nếu bạn sử dụng PriorityBlockingQueue và chỉ sử dụng removeadd (hoặc trực tiếp hơn, offer), thì bạn sẽ an toàn và thậm chí bạn có thể thực hiện trực tiếp từ getQueue().

Nói cách khác, bất cứ khi nào tín hiệu cho bạn biết rằng một số ưu tiên của Runnable đã thay đổi, thì bạn nên remove và kiểm tra kết quả xóa (true nếu bị xóa) và chỉ khi nó thực sự bị xóa, thì bạn nên thêm lại. Bạn không được đảm bảo rằng một thứ gì đó sẽ không được chọn giữa các hoạt động đó, nhưng bạn ít nhất được đảm bảo rằng bạn sẽ không chạy hai lần Runnable, điều này có thể dễ dàng xảy ra nếu được thực hiện với contains ->remove ->add.

Hoặc là, hoặc bạn có thể tự mình viết BlockingQueue sử dụng số Comparator (như số PriorityBlockingQueue) để tìm mức độ ưu tiên cao nhất bất cứ khi nào được yêu cầu cung cấp dữ liệu mới. Điều này nghe có vẻ như rất nhiều công việc cho các giao diện khác nhau có liên quan.

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