39

Tôi đã nghe Java 8 cung cấp rất nhiều tiện ích liên quan đến tính toán đồng thời. Vì vậy, tôi tự hỏi cách đơn giản nhất để song song cho vòng lặp nhất định là gì?Java 8: Vòng lặp song song CHO

public static void main(String[] args) 
{ 
    Set<Server> servers = getServers(); 
    Map<String, String> serverData = new ConcurrentHashMap<>(); 

    for (Server server : servers) 
    { 
     String serverId = server.getIdentifier(); 
     String data = server.fetchData(); 

     serverData.put(serverId, data); 
    } 
} 

Trả lời

44

Đọc trên streams, tất cả chúng đều là cơn thịnh nộ mới.

Chú ý đặc biệt gần gũi với chút thông tin về xử lý song song:

"yếu tố chế biến với một rõ ràng cho vòng vốn đã nối tiếp Streams tạo điều kiện thực hiện song song bởi Tái định hình tính toán như một đường ống dẫn các hoạt động tổng hợp, chứ không phải là. như các hoạt động bắt buộc đối với mỗi phần tử riêng lẻ. Tất cả các hoạt động của luồng có thể thực thi theo thứ tự hoặc song song. "

Vì vậy, để tóm tắt lại, không có song song cho vòng lặp, chúng vốn đã nối tiếp. Tuy nhiên, luồng có thể thực hiện công việc. Hãy nhìn vào đoạn mã sau:

Set<Server> servers = getServers(); 
    Map<String, String> serverData = new ConcurrentHashMap<>(); 

    servers.parallelStream().forEach((server) -> { 
     serverData.put(server.getIdentifier(), server.fetchData()); 
    }); 
+1

Thật tuyệt vời. Cảm ơn bạn –

+0

Eh, tôi đã đưa ra cùng một câu trả lời ... – fge

+4

Lưu ý rằng các luồng song song có phí ở trên: không phải lúc nào cũng cải thiện hiệu suất qua luồng nối tiếp (hoặc bình thường cho mỗi luồng). –

13

Điều đó sẽ được sử dụng một Stream:

servers.parallelStream().forEach(server -> { 
    serverData.put(server.getIdentifier(), server.fetchData()); 
}); 

tôi nghi ngờ một Collector có thể được sử dụng để tác động lớn hơn ở đây, kể từ khi bạn sử dụng một bộ sưu tập đồng thời.

+0

Vâng, sau khi tư vấn cho bạn, tôi bây giờ có thể đọc các biểu thức lambda như cũng như biết một số chi tiết về luồng;) – dosdebug

4

giải pháp elegant Nhiều hơn hoặc chức năng sẽ chỉ sử dụng thu gom toMap hoặc chức năng toConcurrentMap, mà tránh việc duy trì một biến khác stateful cho ConcurrentHashMap, như ví dụ sau:

final Set<Server> servers = getServers(); 
Map<String, String> serverData = servers.parallelStream().collect(
    toConcurrentMap(Server::getIdentifier, Server::fetchData)); 

Lưu ý: 1. Các giao diện chức năng (Server::getIdentifier or Server::fetchData) không cho phép ngoại lệ kiểm tra ném tại đây, 2. Để có được đầy đủ lợi ích của luồng song song, số lượng máy chủ sẽ lớn và không có I/O, xử lý trong các chức năng đó (getIdentifier, fetchData)

Vui lòng tham khảo Người thu gom javadoc tại http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap

-3

sử dụng Parallel.For tôi, mã của bạn có thể trông như sau,

public staic void main(String[] args) 
{ 
    Set<Server> servers = getServers(); 
    Map<String, String> serverData = new ConcurrentHashMap<>(); 

    Parallel.ForEach(servers, new LoopBody<Server>() 
    { 
     public void run(Server server) 
     { 
      String serverId = server.getIdentifier(); 
      String data = server.fetchData(); 

      serverData.put(serverId, data); 
     } 
    }); 
}  
Các vấn đề liên quan