병렬성

여러 작업을 여러 코어가 진짜 동시에 실행하는 것입니다.

동시성 vs 병렬성 비교

동시성 (Concurrency) - 1코어
→ 빠르게 번갈아 실행해서 동시처럼 보임

시간 →
Core1: [A][B][A][B][A][B]

병렬성 (Parallelism) - 멀티코어
→ 진짜 동시에 실행

시간 →
Core1: [A][A][A]
Core2: [B][B][B]

Java에서의 병렬 처리

Fork/Join Framework

// 큰 작업을 작은 단위로 쪼개서 병렬 처리
class SumTask extends RecursiveTask<Long> {
    private long[] array;
    private int start, end;

    @Override
    protected Long compute() {
        if (end - start <= 1000) {
            // 작은 단위 → 직접 계산
            long sum = 0;
            for (int i = start; i < end; i++) sum += array[i];
            return sum;
        }
        // 큰 단위 → 둘로 쪼개서 병렬 처리
        int mid = (start + end) / 2;
        SumTask left  = new SumTask(array, start, mid);
        SumTask right = new SumTask(array, mid, end);
        left.fork();                        // 다른 코어에서 실행
        return right.compute() + left.join(); // 결과 합산
    }
}

Parallel Stream

List<Integer> numbers = List.of(1, 2, 3, 4, 5 ...);

// 일반 Stream - 순차 처리
numbers.stream()
       .map(n -> n * 2)
       .collect(toList());

// Parallel Stream - 멀티코어 병렬 처리
numbers.parallelStream()      // O 내부적으로 Fork/Join 사용
       .map(n -> n * 2)
       .collect(toList());

CompletableFuture

// 여러 작업을 병렬로 실행 후 결과 합산
CompletableFuture<String> task1 =
    CompletableFuture.supplyAsync(() -> "결과1");  // Core1에서 실행

CompletableFuture<String> task2 =
    CompletableFuture.supplyAsync(() -> "결과2");  // Core2에서 실행

// 둘 다 완료되면 합산
CompletableFuture.allOf(task1, task2)
    .thenRun(() -> System.out.println(task1.get() + task2.get()));

병렬성이 무조건 빠른 건 아니다

병렬 처리 비용
├── 작업 분할 비용
├── 스레드 간 통신 비용
├── 결과 합산 비용
└── 컨텍스트 스위칭 비용

작업량이 적으면
병렬 처리 비용 > 성능 향상 → 오히려 느려짐 X

작업량이 충분히 클 때만 병렬 처리가 유리 O

동시성 vs 병렬성 정리

항목동시성병렬성
코어 수1개 이상반드시 2개 이상
실행 방식번갈아 실행진짜 동시 실행
목적응답성 향상처리 속도 향상
적합한 작업I/O 대기, 네트워크CPU 집약적 연산
예시웹 서버 요청 처리이미지 렌더링, 데이터 분석

동시성은 "여러 일을 잘 관리", 병렬성은 "여러 일을 동시에 처리" 입니다. 실무에서는 대부분 두 개념이 함께 사용됩니다. (멀티코어 + 스레드 관리)

CSLOG에서 보기