์ฃผ๋ฅ ์ธ์ด ์ค, ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ ์ธก๋ฉด์์ ์๋ฐ๋ ํญ์ ์์๊ฐ๋ค
์ค๋ ๋, ๋๊ธฐํ, wait/notify๋ฅผ ์ง์ํ๋ค.
wait: ๊ฐ๊ณ ์๋ ๊ณ ์ ๋ฝ์ ํด์ ํ๊ณ , ์ค๋ ๋๋ฅผ ์ ๋ค๊ฒ ํ๋ค.notify:์ ๋ค์ด ์๋ ์ค๋ ๋ ์ค ์์๋ก ํ๋๋ฅผ ๊ณจ๋ผ ๊นจ์ด๋ค.
๋์์ฑ ์ปฌ๋ ์
์ธ java.util.concurrent ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์คํ์(Executor) ํ๋ ์์ํฌ ์ง์ํ๋ค.
๊ณ ์ฑ๋ฅ ๋ณ๋ ฌ ๋ถํด ํ๋ ์์ํฌ์ธ ํฌํฌ-์กฐ์ธ(fork-join) ํจํค์ง๋ฅผ ์ถ๊ฐํ๋ค.
parallel ๋ฉ์๋๋ง ํ ๋ฒ ํธ์ถํ๋ฉด ํ์ดํ๋ผ์ธ์ ๋ณ๋ ฌ ์คํํ ์ ์๋ ์คํธ๋ฆผ์ ์ง์ํ๋ค.
์ด์ฒ๋ผ ๋์์ฑ ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ธฐ ์ ์ ์ฌ์์ง๊ณ ์์ง๋ง, ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์ ํ ๋๋ ํญ์ ์์ ์ฑ(safety)์ ์๋ต ๊ฐ๋ฅ(liveness) ์ํ๋ฅผ ์ ์ง ํด์ผ ํ๋ ๊ฒ์ ์ฃผ์ํด์ผ ํ๋ค.
์คํธ๋ฆผ์ ์ฌ์ฉํด ์ฒ์ 20๊ฐ์ ๋ฉ๋ฅด์ผ ์์๋ฅผ ์์ฑํ๋ ํ๋ก๊ทธ๋จ
๋ฉ๋ฅด์ผ ์์๋? 2์ ๊ฑฐ๋ญ์ ๊ณฑ์์ 1์ ๋บ ํํ์ ์๋ก, ์์์ธ ์๋ฅผ ์๋ฏธํ๋ค.
import java.math.BigInteger;
import java.util.stream.Stream;
public class MersennePrimes {
public static void main(String[] args) {
// ์์๋ฅผ ์์ฑํ๊ณ , ๋ฉ๋ฅด์ผ ์์์ธ์ง ํ์ธ ํ ์์ 20๊ฐ๋ฅผ ์ถ๋ ฅํ๋ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ
primes() // ์์ ์คํธ๋ฆผ ์์ฑ
.map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) // ๋ฉ๋ฅด์ผ ์ ๊ณ์ฐ: 2^p - 1
.filter(mersenne -> mersenne.isProbablePrime(50)) // ๋ฉ๋ฅด์ผ ์๊ฐ ์์์ธ์ง ๊ฒ์ฌ
.limit(20) // ์์ 20๊ฐ์ ๋ฉ๋ฅด์ผ ์์๋ง ๊ฐ์ ธ์ค๊ธฐ
.forEach(System.out::println); // ๊ฐ ๋ฉ๋ฅด์ผ ์์ ์ถ๋ ฅ
}
// ๋ฌดํ ์์ ์คํธ๋ฆผ์ ์์ฑํ๋ ๋ฉ์๋
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime); // 2๋ถํฐ ์์ํ์ฌ ๋ค์ ์์๋ฅผ ๊ณ์ ์์ฑ
}
// ์์ ์ ์
private static final BigInteger TWO = BigInteger.valueOf(2);
private static final BigInteger ONE = BigInteger.ONE;
}์ด ํ๋ก๊ทธ๋จ์ ๋ด ์ปดํจํฐ์์ ์คํํ๋ฉด ์ฆ๊ฐ ์์๋ฅผ ์ฐ๊ธฐ ์์ํด์ 12.5์ด ๋ง์ ์๋ฃ๋๋ค.
์๋๋ฅผ ๋์ด๊ณ ์ถ์ด ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ parallel()์ ํธ์ถํ๊ฒ ๋ค๋์๊ฐ์ ํ๊ณ ์ฌ์ฉ์, ์ฑ๋ฅ์ ์ด๋ป๊ฒ ๋ณํ ๊น๏ผ
@Test
public void mersenne() {
primes()
.parallel()
.map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(mp -> System.out.println(mp.bitLength() + ": " + mp));
}๋ฌด์์ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด parallel() ๋ฅผ ์ฌ์ฉํ๋ฉด, ์์ ๊ฐ์ด ์๋ฌด๊ฒ๋ ์ถ๋ ฅํ์ง ๋ชปํ๋ฉด์ CPU๋ 90% ๋ ์ก์๋จน๋ ์ํ๊ฐ ๋ฌดํํ ๊ณ์๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์คํธ๋ฆผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด ํ์ดํ๋ผ์ธ์ ๋ณ๋ ฌํํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์๋ด์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค
๐ ํ์ดํ๋ผ์ธ ๋ณ๋ ฌํ๋ก ์ฑ๋ฅ ๊ฐ์ ์ ํ ์ ์๋ ๊ฒฝ์ฐ
1. ๋ฐ์ดํฐ ์์ค๊ฐStream.iterate์ธ ๊ฒฝ์ฐ
2. ์ค๊ฐ ์ฐ์ฐ์ผ๋กlimit์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
์์ ์ฝ๋๋ 2๊ฐ์ง์ ๋ฌธ์ ๋ชจ๋๋ฅผ ์ง๋๊ณ ์๋ค.
- ํ์ดํ๋ผ์ธ ๋ณ๋ ฌํ๋ limit ์ด ์์ ๋, CPU ์ฝ์ด๊ฐ ๋จ๋๋ค๋ฉด ์์๋ฅผ ๋ช๊ฐ ๋ ์ฒ๋ฆฌํ ํ ์ ํ๋ ๊ฐ์ ์ดํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฒ๋ ค๋ ์๋ฌด๋ฐ ํด๊ฐ ์๋ค๊ณ ๊ฐ์ ํ๋ค.
- ๊ณ์ ๋ฒ๋ ค์ง๊ธฐ ๋๋ฌธ์ ๊ณ์ ์ด์ ๊น์ง์ ๊ฐ์ ๋ค์ ๊ตฌํด์ผ ํ๋ค.
์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ๋ง๊ตฌ์ก์ด๋ก ๋ณ๋ ฌํํ๋ฉด ์ฑ๋ฅ์ด ์คํ๋ ค ๋์ฐํ๊ฒ ๋๋น ์ง ์ ์๋ค.
์คํธ๋ฆผ ๋ณ๋ ฌํ + forEach
{% hint style="success" %}
๋์ฒด๋ก ์คํธ๋ฆผ์ ์์ค๊ฐ ArrayList, HashMap, HashSet, ConcurrentHashMap์ ์ธ์คํด์ค๊ฑฐ๋ ๋ฐฐ์ด, int ๋ฒ์, long ๋ฒ์์ผ ๋ ๋ณ๋ ฌํ์ ํจ๊ณผ๊ฐ ๊ฐ์ฅ ์ข๋ค.
{% endhint %}
ํด๋น ์๋ฃ๊ตฌ์กฐ๋ค์ ์๋์ ๊ฐ์ ๋ ๊ฐ์ง ๊ณตํต์ ์ ์ง๋๋ค.
1. ์ ํ์ฑ
๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ํฌ๊ธฐ๋ก ์ ํํ๊ณ ์์ฝ๊ฒ ๋๋ ์ ์์ด ๋ค์์ ์ค๋ ๋์ ์ผ์ ๋ถ๋ฐฐํ๊ธฐ์ ์ข๋ค. ๋๋๋ ์์
์ Spliterator ๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ฉฐ, Iterable ๊ณผ Stream ์์ ์ป์ ์ ์๋ค.
2. ์ฐธ์กฐ ์ง์ญ์ฑ(locality of reference) ๋ฐ์ด๋จ
์ฐธ์กฐ ์ง์ญ์ฑ์, ๋ค์๊ณผ ๊ฐ์ด ์ธ๊ฐ์ง๋ก ๋๋์ด์ง๋ค.
- ์๊ฐ ์ง์ญ์ฑ : ์ต๊ทผ์ ์ฐธ์กฐ๋ ์ฃผ์๋ ๋น ๋ฅธ ์๊ฐ ๋ด์ ๋ค์ ์ฐธ์กฐ๋๋ ํน์ฑ
- ๊ณต๊ฐ ์ง์ญ์ฑ : ์ฐธ์กฐ๋ ์ฃผ์์ ์ธ์ ํ ์ฃผ์์ ๋ด์ฉ์ด ๋ค์ ์ฐธ์กฐ๋๋ ํน์ฑ
- ์์ฐจ ์ง์ญ์ฑ : ๋ฐ์ดํฐ๊ฐ ์์ฐจ์ ์ผ๋ก ์์ธ์ค ๋๋ ํน์ฑ(๊ณต๊ฐ ์ง์ญ์ฑ)
๐ ์ฐธ์กฐ ์ง์ญ์ฑ
1.๋์: ์ด์ํ ์์์ ์ฐธ์กฐ๋ค์ด ๋ฉ๋ชจ๋ฆฌ์ ์ฐ์ํด์ ์ ์ฅ๋์ด ์๋ ๊ฒฝ์ฐ
2.๋ฎ์: ์ฐธ์กฐ๋ค์ด ๊ฐ๋ฆฌํค๋ ์ค์ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์๋ก ๋จ์ด์ ธ ์๋ ๊ฒฝ์ฐ
์ฐธ์กฐ ์ง์ญ์ฑ์, ์์ฒญํ ๋ฐ์ดํฐ๋ฅผ ์บ์ ๋ฉ๋ชจ๋ฆฌ์์ ์ฐพ์ ํ๋ฅ ์ธ Cache Hit Rate ๊ณผ๋ ๋น๋กํ๋ค. ์ฐธ์กฐ ์ง์ญ์ฑ์ด ๋์ผ๋ฉด ์บ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ์ฐพ์ ์ ์์ผ๋ฏ๋ก ์๋๊ฐ ๋นจ๋ผ์ง์ง๋ง, ๋ฎ๋ค๋ฉด ์ฃผ ๋ฉ๋ชจ๋ฆฌ์์ ์บ์๋ก ๋ค์ ๋ก๋ํ๋ ๊ณผ์ ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ์ ์ก๋์ด ์ค๊ธฐ๋ง์๊ธฐ๋ค๋ฆฌ๋ฉฐ, ๋๋ถ๋ถ์ ์๊ฐ์ด ๋น์ด, ์ฑ๋ฅ์ด ๋ฎ์์ง๋ค.
๊ธฐ๋ณธ ํ์
์ ๋ฐฐ์ด๊ณผ ๊ฐ์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ ์์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ฐ์ํด์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์, ์ฐธ์กฐ ์ง์ญ์ฑ ์ค์์๋ ๊ณต๊ฐ ์ง์ญ์ฑ์ด ์ข์ Cache Hit Rate ์ด ๊ฐ์ฅ ๋๋ค.
ArrayList ๋ Hash ์๋ฃ๊ตฌ์กฐ ๋ํ ๋ด๋ถ์ ์ผ๋ก ๋ฐฐ์ด(ํด์ ํ
์ด๋ธ)์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ์ฐธ์กฐ ์ง์ญ์ฑ์ด ๋๋ค.
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
transient Node<K,V>[] table;
}๊ฒฐ๋ก ์ ์ผ๋ก, ๋ค๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฒํฌ ์ฐ์ฐ์ ๋ณ๋ ฌํ ํ ๋๋ ๋ฐ๋์ ์ฐธ์กฐ ์ง์ญ์ฑ์ ๊ณ ๋ คํ๋๋ก ํ์.
์ข ๋จ ์ฐ์ฐ์์ ์ํํ๋ ์์ ๋์ด ํ์ดํ๋ผ์ธ ์ ์ฒด ์์ ์์ ์๋น ๋น์ค์ ์ฐจ์งํ๋ฉด์ ์์ฐจ์ ์ธ ์ฐ์ฐ์ด๋ผ๋ฉด, ํ์ดํ๋ผ์ธ ๋ณ๋ ฌ ์ํ์ ํจ๊ณผ๊ฐ ๋จ์ด์ง๋ค.
๋ณ๋ ฌํ๋ ์์ ์ ์ฌ๋ฌ ์ค๋ ๋๋ก ๋ถํ ํ์ฌ ๋์์ ์ฒ๋ฆฌํจ์ผ๋ก์จ ์ฑ๋ฅ ํฅ์์ ๋๋ชจํ๋ ๊ธฐ๋ฒ์ด๋ค. ํ์ง๋ง ๋ชจ๋ ์คํธ๋ฆผ ์์ ์ด ๋ณ๋ ฌํ์ ์ ํฉํ์ง๋ ์๊ธฐ ๋๋ฌธ์, ๋ณ๋ ฌํ๋ฅผ ์ ์ฉํ ๋๋ ์์ ์ ํน์ฑ์ ๊ณ ๋ คํด์ผ ํ๋ค.
์ถ์(reduction) ์ฐ์ฐ์ ์ฌ๋ฌ ๊ฐ์ ํ๋๋ก ์ค์ด๋ ์์ ์ผ๋ก, ๋ณ๋ ฌํ์ ๋งค์ฐ ์ ํฉํ๋ค. ๋ฐ์ดํฐ์ ์ผ๋ถ๋ถ์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ค๋ ๋์์ ์ฒ๋ฆฌํ ํ ๊ฒฐํฉํ๊ธฐ๊ฐ ์ฌ์ด ์์ ๋ค์ด ๋ณ๋ ฌํ์ ํจ๊ณผ๋ฅผ ๊ทน๋ํํ ์ ์๋ค.
- ์ ํฉํ ์ถ์ ์ฐ์ฐ:
min(),max(): ์ต์๊ฐ, ์ต๋๊ฐ ์ฐพ๊ธฐ.count(),sum(): ์์์ ๊ฐ์๋ ํฉ์ ๊ณ์ฐํ๋ ์ฐ์ฐ.- ์ด๋ค ์ฐ์ฐ์ ์ฝ๊ฒ ์ชผ๊ฐ์ ๊ฐ ๋ถ๋ถ์ ์ฒ๋ฆฌํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๊ฒฐํฉํ๋ ๋ฐฉ์์ผ๋ก ์ฑ๋ฅ์ ๋์ผ ์ ์์ต๋๋ค.
- ์กฐ๊ฑด์ ๋ง์ผ๋ฉด ๋ฐ๋ก ๋ฐํํ๋ ๋จ๋ฝ(short-circuiting) ์ฐ์ฐ๋ ๋ณ๋ ฌํ์ ์ ํฉํ๋ค.
anyMatch(): ์กฐ๊ฑด์ ๋ง์กฑํ๋ ํ๋์ ์์๋ผ๋ ์ฐพ์ผ๋ฉด ๋ฐ๋ก ์ข ๋ฃ.allMatch(),noneMatch(): ๋ชจ๋ ์์๊ฐ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ํ์ธ.
์ด๋ค ๋ฉ์๋๋ ์กฐ๊ฑด์ด ๋ง์กฑ๋๋ฉด ์ฆ์ ์ข ๋ฃํ ์ ์์ด, ๋ฐ์ดํฐ ๋ถํ ํ ์ผ๋ถ๋ง ํ์ธํด๋ ์ฑ๋ฅ ํฅ์์ด ๊ฐ๋ฅํ๋ค.
๋ค์์ 2๋ถํฐ n๊น์ง์ ์์๋ฅผ ๊ตฌํ๋ ๋ณ๋ ฌํ ์ฝ๋์ด๋ค. ์ซ์๋ฅผ ๋ฒ์๋ณ๋ก ๋๋๊ณ ๊ฐ๊ฐ์ ์ค๋ ๋์์ ์์์ธ์ง ํ๋ณํ ํ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐํฉํ๋ค.
public long pi(long n) {
return LongStream.range(2, n) // 2๋ถํฐ n-1๊น์ง์ ์ซ์๋ฅผ ์์ฑ
.parallel() // ๋ณ๋ ฌ ์ฒ๋ฆฌ (์ฑ๋ฅ ํฅ์์ ์ํด ์ฌ์ฉ)
.mapToObj(BigInteger::valueOf) // ๊ฐ ์ซ์๋ฅผ BigInteger๋ก ๋ณํ
.filter(i -> i.isProbablePrime(50)) // ์์์ธ์ง ํ๋ฅ ์ ์ผ๋ก ํ์ธ (50๋ฒ ํ
์คํธ)
.count(); // ์์์ ๊ฐ์๋ฅผ ๋ฐํ
}parallel(): ์คํธ๋ฆผ์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ์ฌ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ค.- ํจ๊ณผ:
- ๋ณ๋ ฌํ๊ฐ ์ ์ ์ฉ๋๋ฉด ์ฌ๋ฌ ์ซ์๋ฅผ ๋์์ ์์ ํ๋ณํ๋ฏ๋ก, ์ฑ๋ฅ์ด ์ฝ 5๋ฐฐ ์ด์ ํฅ์๋ ์ ์๋ค.
- ์ ์ฝ๋๋ ์ชผ๊ฐ๊ธฐ ์ฌ์ด ์์ ์ด๊ธฐ ๋๋ฌธ์ ๋ณ๋ ฌํ๊ฐ ํจ๊ณผ์ ์ด๋ค.
- Spliterator ์ฌ์ ์: ์ปค์คํ
๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์คํธ๋ฆผ์ผ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌํ๋ ค๋ฉด, ๋ฐ์ดํฐ์ ์ชผ๊ฐ๊ธฐ์ ํ์์ ํจ์จ์ ์ผ๋ก ํ๊ธฐ ์ํด Spliterator๋ฅผ ์ฌ์ ์ํ๋ ๊ฒ์ด ์ค์ํ๋ค.
- Spliterator๋ ๋ฐ์ดํฐ๋ฅผ ๋ถํ (splitting)ํ๊ณ , ํ์(iteration)ํ๋ ์ธํฐํ์ด์ค๋ก, ๋ณ๋ ฌํ๋ฅผ ์ ์ํํ ์ ์๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถํ ํ๋ ์ญํ ์ ํ๋ค.
- ๋ณ๋ ฌํ ์ฑ๋ฅ ํ ์คํธ: ๋ณ๋ ฌ ์คํธ๋ฆผ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ, ํญ์ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํตํด ์ค์ ๋ก ๋ณ๋ ฌํ๊ฐ ํจ์จ์ ์ธ์ง ๊ฒ์ฆํด์ผ ํ๋ค. ์๋ชป๋ ๋ณ๋ ฌํ๋ ์ฑ๋ฅ์ ์คํ๋ ค ์ ํ์ํฌ ์ ์๋ค.
- ๊ฒฐํฉ ๋ฒ์น(Associativity):
- ๋ณ๋ ฌํ์์๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ์์ ํ ๊ฒฐ๊ณผ๋ฅผ ์ต์ข ์ ์ผ๋ก ๊ฒฐํฉํด์ผ ํ๋ค. ์ด๋ ์ฌ์ฉ๋๋ accumulator์ combiner ํจ์๊ฐ ๊ฒฐํฉ ๋ฒ์น์ ์ง์ผ์ผ ๋ณ๋ ฌํ๋ ์์ ์ ๊ฒฐ๊ณผ๊ฐ ์ ํํ๋ค.
- ๊ฐ์ญ(Interference):
- ์คํธ๋ฆผ ์์ ์ค๊ฐ์ ์ธ๋ถ ์ํ๋ฅผ ์ฐธ์กฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ณ๋ ฌํ์์ ์์ ์คํจ(safety failure)๋ฅผ ์ ๋ฐํ ์ ์๋ค. ๋ณ๋ ฌํ๋ ์คํธ๋ฆผ ์์ ์์ ์ธ๋ถ ์ํ์์ ๊ฐ์ญ์ ์์์น ๋ชปํ ๋์์ ์ด๋ํ๋ฏ๋ก ํผํด์ผ ํ๋ค.
- ์ํ๋ฅผ ๊ฐ์ง ์์์ผ ํจ:
- ๋ณ๋ ฌ ์ฐ์ฐ์ ์ฌ์ฉ๋๋ ํจ์๋ ์ํ๋ฅผ ๊ฐ์ง ์์์ผ ํ๋ค. ์ฆ, ๊ณต์ ๋ ๊ฐ๋ณ ์ํ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ฉ๋๋ค. ์ด๋ฅผ ์งํค์ง ์์ผ๋ฉด ๋ณ๋ ฌ ์คํธ๋ฆผ์ ๊ฒฐ๊ณผ๊ฐ ์๋ชป๋ ์ ์๋ค.
- ์ฑ๋ฅ ์ ํ: ์์ ์ด ๋ณ๋ ฌํ์ ์ ํฉํ์ง ์๊ฑฐ๋, ์์ ๊ฐ์ ๊ฒฝ์ ์กฐ๊ฑด์ด ๋ฐ์ํ๋ฉด ์ฑ๋ฅ์ด ์คํ๋ ค ๋ ๋๋น ์ง ์ ์๋ค.
- ์์์น ๋ชปํ ๋์:
- ๋ณ๋ ฌํ๋ ์์ ์์ ๊ณต์ ์์์ ๋๊ธฐํ ์์ด ์ ๊ทผํ๋ฉด ์๋ชป๋ ๊ฒฐ๊ณผ๋ ๋ฐ์ดํฐ ์ค์ผ์ด ๋ฐ์ํ ์ ์๋ค.
- ์๋ฅผ ๋ค์ด,
Randomํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ด๋ถ์ ์ผ๋ก ๋๊ธฐํ๊ฐ ๋์ด ์์ด ๋ณ๋ ฌํ ์ฑ๋ฅ์ด ๋๋น ์ง ์ ์๋ค.
SplittableRandom:- ๋ณ๋ ฌํ๋ ์์
์์ ๋์๋ฅผ ์์ฑํ ๋๋
SplittableRandom์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. Randomํด๋์ค๋ ๋ด๋ถ์ ์ผ๋ก ๋๊ธฐํ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ํ ๊ฒฝ์ฐ ๊ฒฝ์ ์กฐ๊ฑด์ด ๋ฐ์ํ์ฌ ์ต์ ์ ์ฑ๋ฅ์ ๋ณด์ผ ์ ์๋ค.SplittableRandom์ ๋ณ๋ ฌ ํ๊ฒฝ์์ ๋์๋ฅผ ์์ฑํ๋ ๋ฐ ์ต์ ํ๋ ํด๋์ค
- ๋ณ๋ ฌํ๋ ์์
์์ ๋์๋ฅผ ์์ฑํ ๋๋
import java.util.SplittableRandom;
import java.util.stream.IntStream;
public class ParallelRandomStream {
public static void main(String[] args) {
SplittableRandom random = new SplittableRandom();
// ๋ณ๋ ฌ ์คํธ๋ฆผ์ ์ฌ์ฉํ์ฌ ๋ฌด์์ ์ซ์ ์์ฑ ๋ฐ ์ถ๋ ฅ
IntStream.generate(() -> random.nextInt(100)) // 0๋ถํฐ 99 ์ฌ์ด์ ๋ฌด์์ ์ซ์ ์์ฑ
.parallel() // ๋ณ๋ ฌ ์ฒ๋ฆฌ
.limit(10) // 10๊ฐ์ ์ซ์๋ง ์์ฑ
.forEach(System.out::println);
}
}- ์ค๋ช
:
SplittableRandom์ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ต์ ํ๋ ๋์ ์์ฑ๊ธฐ์ด๋ฏ๋ก, ๋ณ๋ ฌ ์คํธ๋ฆผ์์ ์ฌ์ฉํด๋ ์ฑ๋ฅ ์ ํ ์์ด ์์ ํ๊ฒ ๋์๋ฅผ ์์ฑํ ์ ์๋ค.
| ํน์ฑ | Random |
SplittableRandom |
|---|---|---|
| ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ต์ ํ | ๋๊ธฐํ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ๋ถ์ ํฉ | ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ต์ ํ (๋ ๋ฆฝ์ ์ธ ๋ถํ ๊ฐ๋ฅ) |
| ๋๊ธฐํ | ๋ด๋ถ ์ํ ๋ณดํธ๋ฅผ ์ํด ๋๊ธฐํ ํ์ | ๋๊ธฐํ ๋ถํ์ |
| ๋์ ์์ฑ ๋ฐฉ์ | ์ ํ ํฉ๋ ์์ฑ๊ธฐ (LCG) | ๋ถํ ๊ฐ๋ฅํ ๋์ ์์ฑ๊ธฐ |
| ๋ณ๋ ฌ ์คํธ๋ฆผ ์ฌ์ฉ | ์ฑ๋ฅ ์ ํ ๋ฐ์ ๊ฐ๋ฅ | ์ฑ๋ฅ ์ ํ ์์ด ์ฌ์ฉ ๊ฐ๋ฅ |
์ ํฉํ ์ข ๋จ ์ฐ์ฐ
์ถ์(reduction) ์ฐ์ฐ (
min(),max(),count()๋ฑ)๊ณผ ์กฐ๊ฑด๋ถ ๋ฐํ ์ฐ์ฐ (anyMatch(),allMatch())์ ๋ณ๋ ฌํ์ ์ ํฉํ๋ค.
reduceanyMatch,allMatch,noneMatch- ๋ฐ์ดํฐ๋ฅผ ์ชผ๊ฐ๊ณ ๊ฒฐํฉํ๊ธฐ ์ฌ์ด ์์ ์ผ์๋ก ๋ณ๋ ฌํ์ ํจ๊ณผ๊ฐ ํฌ๋ค.
๋์ ์ข ๋จ ์ฐ์ฐ
collect ์ ๊ฐ์ด ์ปฌ๋ ์
๋ค์ ํฉ์น๋ ๋ถ๋ด์ด ํฐ ๋ฉ์๋๋ ๋ณ๋ ฌํ์ ์ ํฉํ์ง ์๋ค.
๋ณ๋ ฌํ ์ ์ฉ ์ ์ฃผ์์ฌํญ:
- Spliterator๋ฅผ ์ฌ์ ์ํ๊ณ ์ฑ๋ฅ์ ์ถฉ๋ถํ ํ ์คํธํ ํ ๋ณ๋ ฌํ๋ฅผ ์ ์ฉํด์ผ ํ๋ค.
- ๊ฒฐํฉ ๋ฒ์น๊ณผ ๊ฐ์ญ ๊ธ์ง ์กฐ๊ฑด์ ์ง์ผ์ผ ํ๋ค.
- ๋ณ๋ ฌ ์ฐ์ฐ์์๋ ๊ณต์ ์ํ๊ฐ ์๋ ํจ์๋ง ์ฌ์ฉํด์ผ ์์ ํ๋ค.
์๋ชป๋ ๋ณ๋ ฌํ์ ๋ฌธ์ ํด๊ฒฐ:
- Random ๋์ SplittableRandom์ ์ฌ์ฉํ์ฌ ๋ณ๋ ฌ ํ๊ฒฝ์์ ๋์๋ฅผ ์์ ํ๊ฒ ์์ฑํ๋ค.
- ๋ณ๋ ฌ ์คํธ๋ฆผ์ ์ฌ์ฉํ ๋๋ ํญ์ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํตํด ๋ณ๋ ฌํ๊ฐ ํจ๊ณผ์ ์ธ์ง ํ์ธํด์ผ ํ๋ค.
์๊ฐํด๋ด์ผ ํ ๋ถ๋ถ
- ๋ณ๋ ฌํ๊ฐ ํญ์ ์ฑ๋ฅ์ ํฅ์์ํค๋๊ฐ?:
- ๋ณ๋ ฌํ๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์ฑ๋ฅ์ ํฅ์์ํค์ง ์์ต๋๋ค. ์์ ์ ๋น์ฉ, ๋ฐ์ดํฐ ํฌ๊ธฐ, ๋ณ๋ ฌ ์์ ์ ๋ถํ ์ฉ์ด์ฑ ๋ฑ์ ๊ณ ๋ คํ์ฌ ๋ณ๋ ฌํ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ ํฌ๊ธฐ๊ฐ ์๊ฑฐ๋ ์์ ์ ์ค๋ฒํค๋๊ฐ ํด ๊ฒฝ์ฐ, ๋ณ๋ ฌํ๋ฅผ ์ ์ฉํ๋ฉด ์ฑ๋ฅ์ด ์คํ๋ ค ์ ํ๋ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ์ ๊ฒฐํฉ์ด ์ ์ด๋ฃจ์ด์ง๋๊ฐ?:
- ๋ณ๋ ฌํ๋ ์์ ์์๋ ๋ฐ์ดํฐ์ ๊ฒฐํฉ์ด ์ ํํด์ผ ํฉ๋๋ค. ์๋ชป๋ ๊ฒฐํฉ ๋ฐฉ์์ ๊ฒฐ๊ณผ ์ค๋ฅ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ฒฐํฉ ๋ฒ์น์ ํญ์ ์ค์ํด์ผ ํฉ๋๋ค.
- ๋ณ๋ ฌํ ํ
์คํธ:
- ๋ณ๋ ฌํ ํจ๊ณผ๋ฅผ ๊ฒ์ฆํ๊ธฐ ์ํด์๋ ๋ฐ๋์ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํตํด ์ค์ ์ฑ๋ฅ์ด ํฅ์๋๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ณ๋ ฌํ๊ฐ ํจ์จ์ ์ธ์ง ํ๋จํ๊ณ ์ต์ ํ๋ฅผ ์ ์ฉํด์ผ ํฉ๋๋ค.
๋ฌด์์ ๋ณ๋ ฌํ๋ฅผ ํ๋ค๊ณ ์๋๊ฐ ๋นจ๋ผ์ง ๊ฒ์ด๋ผ ์๊ฐํ์ง ๋ง์.
parallel stream ์ ์ค๋ฒํค๋๊ฐ stream ๋ณด๋ค ํจ์ฌ ํฌ๊ธฐ ๋๋ฌธ์, ์ด๋ฅผ ๋ฐ์ด ๋์ ์ ๋๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ํจ์จ์ ์ธ ์์
์ธ ๊ฒฝ์ฐ(ex) ๋น
๋ฐ์ดํฐ) ํ
์คํธ๋ฅผ ํด๋ณด๊ณ ์ฌ์ฉํ๋๋ก ํ์.
- ๋ณ๋ ฌํ ์ ์ค๋์ ๋ฑ์ ๋ถ์์ฉ๋ ํญ์ ๊ณ ๋ คํด์ผ ํ๋ค.
- ์ฑ๋ฅ์งํ1๋ฅผ ํญ์ ์ ์ฌํ ๊ด์ฐฐํ์.
์ถ์ฒ ๋ฐ ์ฐธ๊ณ
Footnotes
-
์ฑ๋ฅ ์งํ๋ฅผ ๊ด์ฐฐํ๊ธฐ ์ํ ๋ค์ํ ํด๊ณผ ๊ธฐ๋ฒ์ด ์๋ค. ์ด๋ฐ ํด๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ CPU ์ฌ์ฉ๋, ๋ฉ๋ชจ๋ฆฌ ์๋น, ์๋ต ์๊ฐ, ์ค๋ ๋ ์ํ ๋ฑ๊ณผ ๊ฐ์ ์ฑ๋ฅ ์งํ๋ฅผ ์์งํ๊ณ ๋ถ์ํ ์ ์๋๋ก ๋์์ค๋ค.
์์ : ์ํญ โฉ
 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png)


.png)