ParallelStream κ³Ό λμμ± λ¬Έμ
μλ° μ μ κ°λ°μ λ©΄μ μ§λ¬Έ μ€μ λ©ν°μ€λ λμ λμμ± λ¬Έμ λ λλΆλΆμ νμ¬μμ λ¨κ³¨ μ§λ¬Έμ ν΄λΉνλ€. μ‘°μ§μ μ£Όλμ΄ κ°λ°μκ° λ©ν°μ€λ λλ₯Ό κ³ λ €νμ§ μκ³ λΉμ¦λμ€ μꡬμ¬νμ μ²λ¦¬νκΈ° μν΄ μ½λλ₯Ό μμ ν κ²°κ³Όλ‘ μΈν΄ μμ€ν μμ μ£Όμ κΈ°λ₯ μ€ νλμΈ μ΄λ²€νΈ λͺ¨λν°λ§ νλ©΄μμ λ°μ΄ν°κ° κ°νμ μΌλ‘ μ¬λ°λ₯΄μ§ μμ λ¬Έμ κ° λ°μν¨μ΄ 리ν¬νΈ λμλ€.
λμμ± λ¬Έμ κ° λ°μνλ μ½λ
λ©ν°μ€λ λμ μν λ³λ ¬ μ²λ¦¬ μ λμμ± λ¬Έμ κ° λ°μνλ λΉμ¦λμ€ λ‘μ§ μ½λλ λμΆ© μλμ κ°λ€κ³ λ³Ό μ μλ€.
List<Customer> customers = IntStream.rangeClosed(1, 100)
.mapToObj(i -> new Customer().setId(String.valueOf(i)))
.toList();
List<String> optIds = new ArrayList<>();
customers.parallelStream().forEach(customer -> {
optIds.add(customer.getId());
// customer μ λν λ°μ΄ν° μ‘°ν λ‘μ§
});
System.out.println("expected: 100, size: " + optIds.size());
μ μ½λμμ ArrayList μ μ μ₯λλ λͺ©λ‘μ κ²°κ³Όκ° λ§€λ² λμΌν¨μ΄ 보μ₯μ΄ λλκ°? κ° μ€μν λΆλΆμΈλ° μ€μ λ‘ ν μ€νΈ μ½λλ₯Ό λλ €λ³΄λ©΄ κ°νμ μΌλ‘ 100κ°κ° μλ 97κ°κ° λͺ©λ‘μ ν¬ν¨λλ κ²½μ°λ₯Ό νμΈν μ μμ κ²μ΄λ€. λ©ν°μ€λ λμ μν΄μ add ν¨μκ° λμμ νΈμΆλλ κ²½μ°μλ ConcurrentModificationExceptionμ κ°μ μμΈκ° λ°μνμ§ μλκ² μ€μν λΆλΆμ΄λ€.
ArrayList μ HashSetμ λν λκΈ°ν 컬λ μ
μΌλ°μ μΌλ‘ λ§μ΄ μ¬μ©λλ ArrayList κ³Ό HashSet μ λ°μ΄ν°λ₯Ό μΆκ°ν λ ParallelStream μ μ¬μ©νλ κ²½μ° μμ κ°μ΄ λμμ± λ¬Έμ λ‘ μΈν΄ μ λλ‘ μΆκ°λμ§ μλ νλͺ©μ΄ μ‘΄μ¬ν μ μλ€. μ΄λ‘ μΈν λμμ± λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μλ μλμ κ°μ΄ Synchronized ν€μλλ₯Ό μ¬μ©νκ±°λ λκΈ°ν λ¬Έμ λ₯Ό κ³ λ €ν 컬λ μ ν΄λμ€λ€μ΄ μ‘΄μ¬νλ€.
- ConcurrentSkipListSet
- CopyOnWriteArrayList
- Collections.synchronizedList();
- CopyOnWriteArraySet
- Collections.synchronizedSet();
- ConcurrentHashMap.newKeySet();
λμμ± λ¬Έμ κ° λ°μνλ λΉμ¦λμ€ λ‘μ§μμ CopyOnWriteArrayList μ CopyOnWriteArraySetμ μ°κΈ° μμ μ λν μ€λ²ν€λκ° μλ€λ μ μ κ³ λ €νμ¬ Collections.synchronizedList λ₯Ό μ¬μ©νλ κ²μΌλ‘ κ²°μ νμ¬ μμ νμλ€.
μλ°μμ λ³λ ¬μ²λ¦¬ μ λμμ±μ κ³ λ €ν΄μΌνλ κ²μ κΈ°μ΄μ μΈ λΆλΆμ ν΄λΉλμ΄ μ£Όλμ΄ κ°λ°μμκ² μμ¬μ΄ λΆλΆμ΄κΈ΄ νλ μ΄λ¬ν λ¬Έμ λ₯Ό λ΄μ¬νκ² λ κ°μ₯ ν° μμΈμ μꡬμ¬νμ μ²λ¦¬ν λΉμμ κ°λ° 리λλ‘μ¨ μ½λ 리뷰λ₯Ό μμΈνκ² ν΄μ£Όμ§ μμλ κ²μ΄λ―λ‘ μ€μ€λ‘ λ°μ±ν΄μΌν λΆλΆμ΄λΌ μκ°λ©λλ€.