IT Share you

자바 8 : 병렬 FOR 루프

shareyou 2020. 12. 4. 21:27
반응형

자바 8 : 병렬 FOR 루프


Java 8은 동시 컴퓨팅과 관련된 많은 유틸리티를 제공한다고 들었습니다. 따라서 주어진 for 루프를 병렬화하는 가장 간단한 방법이 무엇인지 궁금합니다.

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);
    }
}

스트림을 읽으십시오 . 그들은 모두 새로운 분노입니다.

특히 병렬성에 대해주의를 기울이십시오.

"명시적인 for 루프를 사용하여 요소를 처리하는 것은 본질적으로 직렬입니다. 스트림은 계산을 각 개별 요소에 대한 명령 적 작업이 아닌 집계 작업의 파이프 라인으로 재구성하여 병렬 실행을 용이하게합니다. 모든 스트림 작업은 직렬 또는 병렬로 실행할 수 있습니다. "

요약하자면 병렬 for 루프가 없으며 본질적으로 직렬입니다. 그러나 스트림은 작업을 수행 할 수 있습니다. 다음 코드를 살펴보십시오.

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

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

다음을 사용합니다 Stream.

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

Collector동시 수집을 사용하기 때문에 여기서 더 큰 효과를 얻을 수 있다고 생각합니다 .


더 우아하거나 기능적인 솔루션은 다음 예제와 같이 ConcurrentHashMap에 대한 다른 상태 저장 변수를 유지하지 않는 Collectors toMap 또는 toConcurrentMap 함수를 사용하는 것입니다.

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

참고 : 1. 이러한 기능적 인터페이스 ( Server::getIdentifier or Server::fetchData)는 여기에서 확인 된 예외를 허용하지 않습니다. 2. 병렬 스트림의 모든 이점을 얻으려면 서버 수가 많고 I / O가 필요하지 않습니다. 함수 ( getIdentifier, fetchData)

http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap 에서 Collectors javadoc을 참조하십시오.


복사 및 붙여 넣기에 대한 간단한 예제 (위의 예제 Server는 OP에 의해 작성된 사용자 정의 클래스 인 클래스 사용함 ) :

import java.io.Console;
import java.util.ArrayList;

ArrayList<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");
list.parallelStream().forEach((o) -> {
    System.out.print(o);
});

콘솔 출력. 모든 것이 병렬로 실행되므로 순서가 다를 수 있습니다.

Item1
Item2

.parallelStream()방법은 Java v8. 이 예제는 JDK v1.8.0_181.


내 Parallel.For를 사용하여 코드는 다음과 같을 수 있습니다.

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);
        }
    });
}     

참고 URL : https://stackoverflow.com/questions/27558605/java-8-parallel-for-loop

반응형