Một tương lai được thực hiện trên một chuỗi duy nhất. Một số tương lai có thể được thực hiện trên một số chủ đề. Vì vậy, không nhiều hơn về tương lai có thể chiếm một thread đồng thời.
Cách hoạt động? Khi bạn tạo ra một tương lai, điều đó có nghĩa là bạn đã gửi nhiệm vụ tới nhóm chủ đề của mình - nhiệm vụ này không thể song song hoàn toàn do đó nó được thực hiện trên một luồng chỉ. Một hoặc nhiều nhiệm vụ được gửi đến nhóm đang được đưa vào hàng đợi của nhóm, do đó, người thực thi sẽ thực hiện các nhiệm vụ từ hàng đợi đó từng người một và chạy từng công việc trên một số chủ đề được chọn ngẫu nhiên (hoặc cố ý). Vì vậy, một số tương lai có thể nhận được một số chủ đề.
Giới thiệu về đối tượng được chia sẻ - cách duy nhất để thực thi thao tác an toàn cho đối tượng được chia sẻ giữa tương lai là sử dụng Executors.newFixedThreadPool(1)
, nó sẽ chỉ sử dụng một luồng cho toàn bộ nhóm. Một giải pháp khác - là sao chép đối tượng đó cho mọi tương lai. Sử dụng diễn viên (làm cho đối tượng được chia sẻ của bạn là trạng thái của diễn viên) nên là lựa chọn tốt nhất.
Nếu bạn sử dụng một đối tượng cho mỗi tương lai - mọi thứ sẽ ổn.
Lưu ý: Trình xử lý của tương lai, như Future{ ... }.map(handler)
có thể được thực hiện trong chuỗi khác với chính tương lai, nhưng nó thực sự tạo một số khác Future
để nhận kết quả. Tương tự cho flatMap
. Chính xác hơn, họ sử dụng onComplete
mà tạo ra CallbackRunnable
để khởi động xử lý (có thể trong chủ đề khác nhau) sau khi thành công cũ tương lai của - callback này chỉ hoàn thành trong tương lai newely tạo, vì vậy vẫn "không có nhiều hơn một thread mỗi tương lai"
Cảm ơn! Đó chính xác là thông tin tôi đang tìm kiếm. Chỉ cần một câu hỏi tiếp theo nhanh - có lợi thế nào khi gửi nhiều tương lai cho một newFixedThreadPool chỉ với một luồng không? Có thể tính toán đồng thời trên một sợi đơn không? –
Không có lợi thế về hiệu suất nào cả. Điều duy nhất nó có thể cung cấp cho bạn là API asynchoronous (nộp nhiều nhiệm vụ + đăng ký hoàn thành của họ). Bạn cũng có thể tạo ra một số hồ bơi cho các loại tương lai khác nhau, nhưng các diễn viên là tốt hơn cho điều đó. – dk14
Tạo một 'ExecutionContext' từ' Executors.newFixedThreadPool (1) 'với' implicit val executionContext = ExecutionContext.fromExecutorService (Executors.newFixedThreadPool (1)) '. – jpcooper