π 1. μλ°μ λμμ± νλ‘κ·Έλλ°
μλ°λ λμμ± νλ‘κ·Έλλ° μΈ‘λ©΄μμ νμ μμκ°λ€.
- μ²μ 릴리μ€λ 1996λ
μ€λ λ, λκΈ°ν, wait/notify μ§μ - μλ° 5
λμμ± μ»¬λ μ μΈ java.util.concurrent λΌμ΄λΈλ¬λ¦¬μ μ€νμ(Executor) νλ μμν¬ μ§μ - μλ° 7
κ³ μ±λ₯ λ³λ ¬ λΆν΄(parallel decom-position) νλ μμν¬μΈ ν¬ν¬-μ‘°μΈ(fork-join) ν¨ν€μ§ μΆκ° - μλ° 8
parallel λ©μλλ§ ν λ² νΈμΆνλ©΄ νμ΄νλΌμΈμ λ³λ ¬ μ€νν μ μλ μ€νΈλ¦Ό μ§μ
μ΄μ²λΌ μλ°λ‘ λμμ± νλ‘κ·Έλ¨μ μμ±νκΈ°κ° μ μ μ¬μμ§κ³ μλ€. νμ§λ§, λμμ± νλ‘κ·Έλλ°μ ν λλ μμ μ±(safety)κ³Ό μλ΅ κ°λ₯(liveness) μνλ₯Ό μ μ§νκΈ° μν΄ μ μ¨μΌ νλ€. λ³λ ¬ μ€νΈλ¦Ό νμ΄νλΌμΈ νλ‘κ·Έλλ°μμλ λ§μ°¬κ°μ§λ€.
π 2. μ±κ³΅μ μΈ μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬ν
μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬νμ ν¨κ³Όλ₯Ό λ¨Όμ μμ보μ.
λ€μκ³Ό κ°μ΄ nλ³΄λ€ μκ±°λ κ°μ μμμ κ°μλ₯Ό κ³μ°νλ ν¨μκ° μλ€κ³ ν΄λ³΄μ. λ³λ ¬νλ₯Ό νμ§ μμ κ²½μ°μ λ³λ ¬νλ₯Ό ν κ²½μ°λ λ€μκ³Ό κ°λ€.
// λ³λ ¬νλ₯Ό νμ§ μμ κ²½μ°
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
// λ³λ ¬νλ₯Ό ν κ²½μ°
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.parallel()
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
ν΄λΉ μ½λλ₯Ό μ΄μ©νμ¬ 10^7(10_000_000)μ κ³μ°νμμ λ, λ³λ ¬ν μ μλ 26μ΄κ° κ±Έλ Έκ³ λ³λ ¬ν νμλ 10μ΄κ° κ±Έλ Έλ€.
μ¦, λ³λ ¬νλ₯Ό ν΅ν΄ 2.6λ°°μ μ±λ₯ ν₯μμ λ³Έ κ²μ΄λ€.
π 3. μλͺ»λ μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬ν
λ€μμ μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬νλ₯Ό μ λͺ» μ¬μ©ν μλ₯Ό μ΄ν΄λ³΄μ.
μμλ μμ΄ν 45(λ§ν¬)μμ λ€λ£¨μλ λ©λ₯΄μΌ μμλ₯Ό μμ±νλ νλ‘κ·Έλ¨μ΄λ€.
private static final int COUNT = 20;
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(COUNT)
.forEach(System.out::println);
}
μ΄ μ½λλ λ³λ ¬νλ₯Ό ν κ²½μ°κ° λ³λ ¬νλ₯Ό νκΈ° μ λ³΄λ€ λ λΉ¨λΌμ‘μκΉ?
μλλ€. λ³λ ¬νλ₯Ό νκ² λλ€λ©΄ μ΄ κ²½μ° μ무κ²λ μΆλ ₯νμ§ λͺ»νλ©΄μ μλ΅λΆκ°(liveness) μνκ° λλ€. κ·Έ μ΄μ λ μ€νΈλ¦Ό λΌμ΄λΈλ¬λ¦¬κ° μ΄ νμ΄νλΌμΈμ λ³λ ¬ννλ λ°©λ²μ μ°Ύμλ΄μ§ λͺ»νκΈ° λλ¬Έμ΄λ€.
λ°μ΄ν° μμ€κ° Stream.iterate κ±°λ μ€κ° μ°μ°μΌλ‘ limitμ μ°λ©΄ νμ΄νλΌμΈ λ³λ ¬νλ‘λ μ±λ₯ κ°μ μ κΈ°λν μ μλ€. νμ΄νλΌμΈ λ³λ ¬νλ limitμ λ€λ£° λ CPU μ½μ΄κ° λ¨λλ€λ©΄ μμλ₯Ό λͺ κ° λ μ²λ¦¬ν ν μ νλ κ°μ μ΄νμ κ²°κ³Όλ₯Ό λ²λ €λ μλ¬΄λ° ν΄κ° μλ€κ³ κ°μ νκΈ° λλ¬Έμ΄λ€. λ€μ μμλ₯Ό μ°Ύλ λ° κ±Έλ¦¬λ μκ°μ΄ μ΄μ μμλ₯Ό μ°Ύλ λ° κ±Έλ¦¬λ μκ°λ³΄λ€ λ λ§μ΄ 거리기 λλ¬Έμ λ³λ ¬νκ° μ κΈ°λ₯μ λ°ννμ§ λͺ»ν κ²μ΄λ€.
π 4. μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬νλ₯Ό μ μ©νλ κΈ°μ€
λμ²΄λ‘ μ€νΈλ¦Ό μμ€κ° ArrayList, HashMap, HashSet, ConcurrentHashMapμ μΈμ€ν΄μ€ κ±°λ λ°°μ΄, int λ²μ, long λ²μμΌ λ λ³λ ¬νμ ν¨κ³Όκ° κ°μ₯ μ’λ€. μ΄ μλ£κ΅¬μ‘°λ€μ λͺ¨λ λ°μ΄ν°λ₯Ό μνλ ν¬κΈ°λ‘ μ ννκ³ μμ½κ² λλ μ μμ΄μ μΌμ λ€μμ μ€λ λμ λΆλ°°νκΈ° μ’λ€λ νΉμ§μ΄ μλ€.
λν, μ΄ μλ£κ΅¬μ‘°λ€μ μμλ€μ μμ°¨μ μΌλ‘ μ€νν λ μ°Έμ‘° μ§μμ±(locality of reference)μ΄ λ°μ΄λκΈ° λλ¬Έμ λ€λμ λ°μ΄ν°λ₯Ό μ²λ¦¬νλ λ²ν¬ μ°μ°μ λ³λ ¬νν λ μ΄μ μ΄ μλ€.
μ€νΈλ¦Ό νμ΄νλΌμΈμ μ’ λ¨ μ°μ°μ λμ λ°©μ μμ λ³λ ¬ μν ν¨μ¨μ μν₯μ μ€λ€. μ’ λ¨ μ°μ°μμ μννλ μμ λμ΄ νμ΄νλΌμΈ μ 체 μμ μμ μλΉ λΉμ€μ μ°¨μ§νλ©΄μ μμ°¨μ μΈ μ°μ°μ΄λΌλ©΄ νμ΄νλΌμΈ λ³λ ¬ μνμ ν¨κ³Όλ μ νλ μλ°μ μλ€.
- νμ΄νλΌμΈμμ λ§λ€μ΄μ§ λͺ¨λ μμλ₯Ό νλλ‘ ν©μΉλ μμ μΈ μΆμ(reduction)κ° λ³λ ¬νμ μ ν©ν μ’ λ¨ μ°μ°μ΄λ€. (ex. min, max, count, sum)
- 쑰건μ λ§μΌλ©΄ λ°λ‘ λ°νλλ λ©μλλ λ³λ ¬νμ μ ν©νλ€. (ex. anyMatch, allMatch, noneMatch)
- 컬λ μ μ ν©μΉλ λΆλ΄μ΄ ν° κ°λ³ μΆμ(mutable reduction)λ λ³λ ¬νμ μ ν©νμ§ μλ€.
μ€νΈλ¦Όμ μλͺ» λ³λ ¬ννλ©΄ (μλ΅ λΆκ°λ₯Ό ν¬ν¨ν΄) μ±λ₯μ΄ λλΉ μ§ λΏλ§ μλλΌ κ²°κ³Ό μμ²΄κ° μλͺ»λκ±°λ μμ λͺ»ν λμμ΄ λ°μν μ μλ€. λ°λΌμ, κ³μ°λ μ¬λ°λ₯΄κ³ μ±λ₯λ λΉ¨λΌμ§ κ±°λΌλ νμ μμ΄λ μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬νλ μλμ‘°μ°¨ νμ§ λ§μ. μ€νΈλ¦Όμ μλͺ» λ³λ ¬ννλ©΄ νλ‘κ·Έλ¨μ μ€λμνκ² νκ±°λ μ±λ₯μ κΈκ²©ν λ¨μ΄λ¨λ¦°λ€.
λν, λ³λ ¬νλ₯Ό νλ κ² λ«λ€κ³ νλ¨μ΄ λλ©΄, μ΄μ μμ€ν κ³Ό ν‘μ¬ν νκ²½μμ ν μ€νΈλ₯Ό μ§ννλλ‘ νμ.
ν΄λΉ κΈμ Joshua Bloch λμ 'Effective Java 3/E'λ₯Ό μ°Έκ³ νμμ΅λλ€.