2015-03-23 14 views
66

Tôi muốn xử lý danh sách bên trong đối tượng java XML. Tôi phải đảm bảo xử lý tất cả các yếu tố theo thứ tự tôi nhận được chúng.Làm thế nào để đảm bảo thứ tự xử lý trong luồng java8?

Tôi có nên gọi sequential trên mỗi stream tôi sử dụng không? list.stream().sequential().filter().forEach()

Hoặc có đủ để chỉ sử dụng luồng miễn là tôi không sử dụng song song không? list.stream().filter().forEach()

Trả lời

188

Bạn đang đặt câu hỏi sai. Bạn đang hỏi về sequential so với parallel trong khi bạn muốn xử lý các mục theo thứ tự, vì vậy bạn phải hỏi về đặt hàng. Nếu bạn có một số , hãy yêu cầu luồng và thực hiện các hoạt động đảm bảo duy trì thứ tự, không quan trọng liệu luồng có được xử lý song song hay tuần tự hay không; việc thực hiện sẽ duy trì thứ tự.

Thuộc tính được sắp xếp khác với song song so với tuần tự. Ví dụ. nếu bạn gọi số stream() trên số HashSet, luồng sẽ không có thứ tự trong khi gọi stream() trên số List trả lại luồng đã đặt hàng. Lưu ý rằng bạn có thể gọi unordered() để phát hành hợp đồng đặt hàng và có khả năng tăng hiệu suất. Khi luồng không có thứ tự thì không có cách nào để thiết lập lại thứ tự. (Cách duy nhất để chuyển một luồng không theo thứ tự thành một lệnh được gọi là sorted, tuy nhiên, thứ tự kết quả không nhất thiết là thứ tự ban đầu).

Xem thêm số “Ordering” section của số java.util.stream package documentation.

Để đảm bảo duy trì trật tự trong toàn bộ hoạt động của luồng, bạn phải nghiên cứu tài liệu về nguồn của luồng, tất cả hoạt động trung gian và hoạt động đầu cuối cho dù chúng có duy trì thứ tự hay không (hoặc liệu nguồn có đặt hàng ở nơi đầu tiên).

Điều này có thể rất tinh tế, ví dụ: Stream.iterate(T,UnaryOperator) tạo luồng đã đặt hàng trong khi Stream.generate(Supplier) tạo một luồng không theo thứ tự. Lưu ý rằng bạn cũng đã mắc một lỗi phổ biến trong câu hỏi của mình là forEachkhông duy trì thứ tự. Bạn phải sử dụng forEachOrdered nếu bạn muốn xử lý các yếu tố của luồng theo thứ tự được đảm bảo.

Vì vậy, nếu bạn list trong câu hỏi của bạn thực sự là một java.util.List, phương pháp của nó stream() sẽ trả về một dòng ra lệnhfilter sẽ không thay đổi thứ tự. Vì vậy, nếu bạn gọi list.stream().filter() .forEachOrdered(), tất cả các phần tử sẽ được xử lý tuần tự theo thứ tự, trong khi đối với list.parallelStream().filter().forEachOrdered(), các phần tử có thể được xử lý song song (ví dụ: bằng bộ lọc) nhưng hành động đầu cuối sẽ vẫn được gọi theo thứ tự (rõ ràng là sẽ làm giảm lợi ích của song song) chấp hành).

Nếu bạn, ví dụ, sử dụng một hoạt động như

List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList()); 

toàn bộ hoạt động có thể được hưởng lợi từ thực hiện song song nhưng danh sách kết quả sẽ luôn luôn được theo thứ tự đúng, bất kể bạn sử dụng một song song hoặc tuần tự suối.

+30

Có, câu trả lời hay. Một điều mà tôi đã tìm thấy là thuật ngữ chúng tôi sử dụng, ít nhất là bằng tiếng Anh, chẳng hạn như "trước", "sau", v.v., khá mơ hồ. Có hai loại đặt hàng tại đây: 1) * lệnh giao dịch * (còn được gọi là * thứ tự không gian *) và 2) * thứ tự xử lý * (còn được gọi là * thứ tự thời gian *). Với sự phân biệt này trong tâm trí nó có thể hữu ích để sử dụng các từ như "trái của" hoặc "bên phải" khi thảo luận về lệnh bắt gặp và "sớm hơn" hoặc "muộn hơn" khi thảo luận về trình tự xử lý. –

1

list.stream(). Tuần tự(). Lọc(). Foreach()

sẽ luôn luôn xử lý danh sách theo thứ tự như danh sách riêng của mình được ra lệnh.

Tuy nhiên nếu chúng ta sử dụng

list.stream(). Song song()

sau đó thứ tự không được bảo đảm cho phần còn lại của các hoạt động.

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