Boris Spider đã vạch ra sự khác biệt rõ ràng nhất giữa ArrayBlockingQueue
và LinkedBlockingQueue
- trước đây luôn bị chặn, trong khi sau đó có thể không bị chặn.
Vì vậy, trong trường hợp bạn cần một hàng đợi chặn không bị chặn, LinkedBlockingQueue
hoặc LinkedTransferQueue
được sử dụng làm BlockingQueue
là các cược tốt nhất của bạn từ hộp công cụ java.util.concurrent
.
Nhưng giả sử bạn cần hàng đợi chặn bị chặn. Cuối cùng, bạn nên chọn triển khai dựa trên thử nghiệm rộng rãi với mô phỏng khối lượng công việc trong thế giới thực của bạn. Tuy nhiên, sau đây là một số lưu ý có thể giúp bạn với sự lựa chọn của bạn hoặc với giải thích các kết quả từ các thí nghiệm:
ArrayBlockingQueue
có thể được tạo ra với một cấu hình (on/off) Chính sách kế hoạch công bằng. Điều này là rất tốt nếu bạn cần sự công bằng hoặc muốn tránh sự đói kém của nhà sản xuất/người tiêu dùng, nhưng nó sẽ khiến bạn mất chi phí.
ArrayBlockingQueue
phân bổ trước mảng sao lưu của nó, vì vậy nó không phân bổ các nút trong quá trình sử dụng, nhưng ngay lập tức lấy những gì có thể là một bộ nhớ đáng kể, có thể là vấn đề nếu bộ nhớ của bạn bị phân mảnh.
ArrayBlockingQueue
nên có ít thay đổi về hiệu suất, vì nó có ít chi tiết hơn, nó sử dụng thuật toán đơn giản và ít phức tạp hơn, không tạo nút trong quá trình sử dụng và hành vi bộ nhớ cache của nó phải tương đối nhất quán.
LinkedBlockingQueue
nên có thông lượng tốt hơn, vì nó sử dụng khóa riêng cho đầu và đuôi.
LinkedBlockingQueue
không phân bổ trước các nút, điều đó có nghĩa là dấu vết bộ nhớ của nó gần bằng kích thước của nó, nhưng nó cũng có nghĩa là nó sẽ phát sinh một số công việc để phân bổ và giải phóng các nút.
LinkedBlockingQueue
có thể sẽ có hành vi bộ nhớ cache tồi tệ hơn, điều này có thể ảnh hưởng đến hiệu suất của riêng nó, mà còn hiệu suất của các thành phần khác do chia sẻ sai.
Tùy thuộc vào tình huống sử dụng của bạn và bao nhiêu bạn quan tâm về hiệu suất, bạn cũng có thể muốn xem xét bên ngoài của java.util.concurrent
và xem xét Disruptor (một đặc biệt nhanh, nhưng hơi chuyên giáp non-blocking vòng đệm) hoặc JCTools (một loạt các hàng đợi bị chặn hoặc không bị ràng buộc với các đảm bảo khác nhau tùy thuộc vào số lượng nhà sản xuất và người tiêu dùng).
Nguồn
2016-03-13 20:32:49
Câu trả lời hay! Tôi đồng ý với những gì bạn đã đề cập đến cũng tôi muốn nhấn mạnh (một lần nữa) thực tế là ArrayBlockingQueue được hỗ trợ bởi một mảng mà kích thước sẽ không bao giờ thay đổi sau khi tạo. Việc đặt công suất thành Integer.MAX_VALUE sẽ tạo ra một mảng lớn với chi phí cao trong không gian. ArrayBlockingQueue luôn bị chặn. LinkedBlockingQueue tạo các nút động cho đến khi đạt được dung lượng. Điều này là theo mặc định Integer.MAX_VALUE. Sử dụng công suất lớn như vậy không có thêm chi phí trong không gian. LinkedBlockingQueue được tùy chọn giới hạn. –