Post

🦊 chap1. μžλ°” 8, 9, 10, 11 : 무슨 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”κ°€?

1.1 μ—­μ‚¬μ˜ 흐름은 무엇인가?

μžλ°” 역사λ₯Ό 톡틀어 κ°€μž₯ 큰 λ³€ν™”κ°€ μžλ°” 8μ—μ„œ 일어났닀.

이런 고전적인 μ½”λ“œλŠ” μžλ°” 8μ—μ„œ μ•„λž˜μ²˜λŸΌ λ°”λ€Œμ—ˆλ‹€.

μžλ°” 8은 κ°„κ²°ν•œ μ½”λ“œ, λ©€ν‹°μ½”μ–΄ ν”„λ‘œμ„Έμ„œμ˜ μ‰¬μš΄ ν™œμš©μ΄λΌλŠ” 두 가지 μš”κ΅¬μ‚¬ν•­μ„ 기반으둜 ν•œλ‹€.

μžλ°” 8μ—μ„œ μ œκ³΅ν•˜λŠ” μƒˆλ‘œμš΄ κΈ°μˆ μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • 슀트림 API
  • λ©”μ„œλ“œμ— μ½”λ“œλ₯Ό μ „λ‹¬ν•˜λŠ” 기법
  • μΈν„°νŽ˜μ΄μŠ€μ˜ λ””ν΄νŠΈ λ©”μ„œλ“œ

μžλ°” 8은 λ°μ΄ν„°λ² μ΄μŠ€ 질의 μ–Έμ–΄μ—μ„œ ν‘œν˜„μ‹μ„ μ²˜λ¦¬ν•˜λŠ” κ²ƒμ²˜λŸΌ 병렬 연산을 μ§€μ›ν•˜λŠ” μŠ€νŠΈλ¦Όμ΄λΌλŠ” μƒˆλ‘œμš΄ API λ₯Ό μ œκ³΅ν•œλ‹€.

κ³ μˆ˜μ€€ μ–Έμ–΄λ‘œ μ›ν•˜λŠ” λ™μž‘μ„ ν‘œν˜„ν•˜λ©΄, κ΅¬ν˜„λΆ€μ—μ„œ 졜적의 μ €μˆ˜μ€€ μ‹€ν–‰ 방법을 μ„ νƒν•˜λŠ” λ°©μ‹μœΌλ‘œ λ™μž‘ν•œλ‹€.

μŠ€νŠΈλ¦Όμ„ μ΄μš©ν•˜λ©΄ μ—λŸ¬λ₯Ό 자주 μΌμœΌν‚€κ³  λΉ„μš©μ΄ 훨씬 λΉ„μ‹Ό synchronized ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

λ©”μ„œλ“œμ— μ½”λ“œλ₯Ό μ „λ‹¬ν•˜λŠ” 기법을 μ΄μš©ν•˜λ©΄ λ™μž‘ νŒŒλΌλ―Έν„°ν™”λ₯Ό μ†μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

μ΄λŠ” ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œ μœ„λ ₯을 λ°œνœ˜ν•œλ‹€.

1.2 μ™œ 아직도 μžλ°”λŠ” μ§„ν™”ν•˜λŠ”κ°€?

1.2.1 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ μƒνƒœκ³„μ—μ„œ μžλ°”μ˜ μœ„μΉ˜

μžλ°”λŠ” 좜발이 μ’‹μ•˜λ‹€.

μ²˜μŒλΆ€ν„° λ§Žμ€ μœ μš©ν•œ 라이브러리λ₯Ό ν¬ν•¨ν•˜λŠ” 잘 μ„€κ³„λœ 객체지ν–₯ μ–Έμ–΄λ‘œ μ‹œμž‘ν–ˆλ‹€.

μŠ€λ ˆλ“œμ™€ 락을 μ΄μš©ν•œ μ†Œμ†Œν•œ λ™μ‹œμ„±λ„ μ§€μ›ν–ˆλ‹€.

ν•˜μ§€λ§Œ λΉ…λ°μ΄ν„°λΌλŠ” 도전에 μ§λ©΄ν•˜λ©΄μ„œ 병렬 ν”„λ‘œμ„Έμ‹±μ„ ν™œμš©ν•΄μ•Ό ν•˜λŠ”λ°,

μ§€κΈˆκΉŒμ§€μ˜ μžλ°”λ‘œλŠ” μΆ©λΆ„νžˆ λŒ€μ‘ν•  수 μ—†μ—ˆλ‹€.

μžλ°” 8에 μΆ”κ°€λœ κΈ°λŠ₯은 μžλ°”μ— μ—†λ˜ μ™„μ „νžˆ μƒˆλ‘œμš΄ κ°œλ…μ΄μ§€λ§Œ

ν˜„μž¬ μ‹œμž₯μ—μ„œ μš”κ΅¬ν•˜λŠ” κΈ°λŠ₯을 효과적으둜 μ œκ³΅ν•œλ‹€.

1.2.2 슀트림 처리

μŠ€νŠΈλ¦Όμ΄λž€ ν•œ λ²ˆμ— ν•œ κ°œμ”© λ§Œλ“€μ–΄μ§€λŠ” 연속적인 데이터 ν•­λͺ©λ“€μ˜ λͺ¨μž„이닀.

μœ λ‹‰μŠ€μ—μ„œλŠ” μžλ™μ°¨ 생산 곡μž₯ 라인처럼 순차적으둜 데이터λ₯Ό μ „μ†‘ν•˜μ§€λ§Œ 각 μž‘μ—…μž₯μ—μ„œλŠ” λ™μ‹œμ— μž‘μ—…μ„ μ²˜λ¦¬ν•œλ‹€.

μžλ°” 8μ—μ„œλŠ” java.util.stream νŒ¨ν‚€μ§€μ— 슀트림 APIκ°€ μΆ”κ°€λ˜μ—ˆλ‹€.

슀트림 API λŠ” νŒŒμ΄ν”„λΌμΈμ„ λ§Œλ“œλŠ” 데 ν•„μš”ν•œ λ§Žμ€ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.

μš°λ¦¬λŠ” μž‘μ—…μ„ κ³ μˆ˜μ€€μœΌλ‘œ μΆ”μƒν™”ν•΄μ„œ 일련의 슀트림으둜 λ§Œλ“€μ–΄ μ²˜λ¦¬ν•  수 μžˆλ‹€.

λ˜ν•œ μŠ€λ ˆλ“œλΌλŠ” λ³΅μž‘ν•œ μž‘μ—…μ„ μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄μ„œλ„ 곡짜둜 병렬성을 얻을 수 μžˆλ‹€.

1.2.3 λ™μž‘ νŒŒλΌλ―Έν„°ν™”λ‘œ λ©”μ„œλ“œμ— μ½”λ“œ μ „λ‹¬ν•˜κΈ°

μžλ°” 8 μ΄μ „μ—λŠ” λ©”μ„œλ“œλ₯Ό λ‹€λ₯Έ λ©”μ„œλ“œλ‘œ 전달할 방법이 μ—†μ—ˆλ‹€.

μžλ°” 8μ—μ„œλŠ” λ©”μ„œλ“œλ₯Ό λ‹€λ₯Έ λ©”μ„œλ“œμ˜ 인수둜 λ„˜κ²¨μ£ΌλŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

μ΄λŸ¬ν•œ κΈ°λŠ₯을 이둠적으둜 λ™μž‘ νŒŒλΌλ―Έν„°ν™”(behavior parameterization)라고 λΆ€λ₯Έλ‹€

1.2.4 병렬성과 곡유 κ°€λ³€ 데이터

보톡 λ‹€λ₯Έ μ½”λ“œμ™€ λ™μ‹œμ— μ‹€ν–‰ν•˜λ”λΌλ„ μ•ˆμ „ν•˜κ²Œ μ‹€ν–‰ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό λ§Œλ“€λ €λ©΄ 곡유된 κ°€λ³€ 데이터에 μ ‘κ·Όν•˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€.

μ΄λŸ¬ν•œ ν•¨μˆ˜λ₯Ό 순수 ν•¨μˆ˜, λΆ€μž‘μš©μ—†λŠ” ν•¨μˆ˜, λ¬΄μƒνƒœ ν•¨μˆ˜λΌκ³  λΆ€λ₯Έλ‹€.

μžλ°” 8 μŠ€νŠΈλ¦Όμ„ ν™œμš©ν•˜λ©΄ 기쑴의 μžλ°” μŠ€λ ˆλ“œ API (synchronized)보닀 μ‰½κ²Œ 병렬성을 ν™œμš©ν•  수 μžˆλ‹€.

1.2.5 μžλ°”κ°€ 진화해야 ν•˜λŠ” 이유

λ§Žμ€ μ΄λŠ” μžλ°”μ˜ 변화에 이미 μ΅μˆ™ν•΄μ Έ 있고 그것이 κ°€μ Έλ‹€μ£ΌλŠ” νŽΈλ¦¬ν•¨μ„ λˆ„λ¦¬κ³  μžˆλ‹€.

예λ₯Ό λ“€λ©΄ μ œλ„€λ¦­μ΄ κ°‘μžκΈ° λ‚˜νƒ€λ‚˜κ³ , List κ°€ List 으둜 λ°”λ€Œκ³ ,

틀에 λ°•νžŒ Iterator λŒ€μ‹  for-each 루프λ₯Ό μ‚¬μš©ν•  수 있게 λ˜μ—ˆλ‹€.

고전적인 객체지ν–₯μ—μ„œ λ²—μ–΄λ‚˜ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ λ‹€κ°€μ„°λ‹€.

μ–Έμ–΄λŠ” ν•˜λ“œμ›¨μ–΄λ‚˜ ν”„λ‘œκ·Έλž˜λ¨Έ κΈ°λŒ€μ˜ 변화에 λΆ€μ‘ν•˜λŠ” λ°©ν–₯으둜 λ³€ν™”ν•΄μ•Ό ν•œλ‹€.

1.3 μžλ°” ν•¨μˆ˜

ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λΌλŠ” μš©μ–΄λŠ” λ©”μ„œλ“œ, 특히 정적 λ©”μ„œλ“œμ™€ 같은 의미둜 μ‚¬μš©λœλ‹€.

μžλ°”μ˜ ν•¨μˆ˜λŠ” 이에 더해 μˆ˜ν•™μ μΈ ν•¨μˆ˜μ²˜λŸΌ μ‚¬μš©λ˜λ©° λΆ€μž‘μš©μ„ μΌμœΌν‚€μ§€ μ•ŠλŠ” ν•¨μˆ˜λ₯Ό μ˜λ―Έν•œλ‹€.

μžλ°” 8μ—μ„œλŠ” ν•¨μˆ˜λ₯Ό μƒˆλ‘œμš΄ κ°’μ˜ ν˜•μ‹μœΌλ‘œ μΆ”κ°€ν–ˆλ‹€.

ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ 핡심은 값을 λ°”κΎΈλŠ” 것이닀.

μ—­μ‚¬μ μœΌλ‘œλ„, μ „ν†΅μ μœΌλ‘œλ„ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œλŠ” 이 값을 일급값 λ˜λŠ” μΌκΈ‰μ‹œλ―ΌμœΌλ‘œ λΆ€λ₯Έλ‹€.

ν”„λ‘œκ·Έλž˜λ°μ„ μ‹€ν–‰ν•˜λŠ” λ™μ•ˆ λͺ¨λ“  ꡬ쑰체λ₯Ό 자유둭게 전달할 μˆ˜λŠ” μ—†λŠ”λ°

μ΄λ ‡κ²Œ 전달할 수 μ—†λŠ” κ΅¬μ‘°μ²΄λŠ” 이급 μ‹œλ―Όμ΄λ‹€.

λ©”μ„œλ“œ, 클래슀 등은 이급 μžλ°” μ‹œλ―Όμ— ν•΄λ‹Ήν•œλ‹€.

μžλ°” 8 μ„€κ³„μžλ“€μ€ 이급 μ‹œλ―Όμ„ 일급 μ‹œλ―ΌμœΌλ‘œ λ°”κΏ€ 수 μžˆλŠ” κΈ°λŠ₯을 μΆ”κ°€ν–ˆλ‹€.

λŸ°νƒ€μž„μ— λ©”μ„œλ“œλ₯Ό 전달할 수 μžˆλ‹€λ©΄ ν”„λ‘œκ·Έλž˜λ°μ— μœ μš©ν•˜κ²Œ ν™œμš©ν•  수 μžˆλ‹€.

1.3.1 λ©”μ„œλ“œμ™€ λžŒλ‹€λ₯Ό 일급 μ‹œλ―ΌμœΌλ‘œ

  • λ©”μ„œλ“œ μ°Έμ‘°

μžλ°” 8μ—μ„œλŠ” λ©”μ„œλ“œκ°€ 이급값이 μ•„λ‹Œ 일급값이닀.

기쑴에 객체 μ°Έμ‘°λ₯Ό μ΄μš©ν•˜μ—¬ 객체λ₯Ό μ£Όκ³  λ°›μ•˜λ˜ 것 처럼 File::isHidden κ³Ό 같이 λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό λ§Œλ“€μ–΄ 전달할 수 있게 λ˜μ—ˆλ‹€.

  • λžŒλ‹€ : 읡λͺ…ν•¨μˆ˜

λžŒλ‹€λ₯Ό ν¬ν•¨ν•œ ν•¨μˆ˜λ„ μΌκΈ‰κ°’μœΌλ‘œ μ·¨κΈ‰ν•  수 μžˆλ‹€.

1.3.2 μ½”λ“œ λ„˜κ²¨μ£ΌκΈ° : 예제

νŠΉμ • ν•­λͺ©μ„ μ„ νƒν•΄μ„œ λ°˜ν™˜ν•˜λŠ” λ™μž‘μ„ 필터라고 ν•œλ‹€.

μžλ°” 8 μ΄μ „μ—λŠ” λ‹€μŒμ²˜λŸΌ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν–ˆμ„ 것이닀.

λˆ„κ΅°κ°€λŠ” 사과λ₯Ό 무게둜 ν•„ν„°λ§ν•˜κ³  싢을 μˆ˜λ„ μžˆλ‹€.

μ΄λŸ¬ν•œ λ³€ν™”λŠ” 보톡 볡사&λΆ™μ—¬λ„£κΈ°λ‘œ 이루어진닀.

λ§Œμ•½ μ–΄λ–€ μ½”λ“œμ— 버그가 μžˆλ‹€λ©΄ 볡사 λΆ™μ—¬λ„£κΈ°ν•œ λͺ¨λ“  μ½”λ“œλ₯Ό κ³ μ³μ•Όν•˜λŠ” 단점이 μžˆλ‹€.

μžλ°” 8μ—μ„œλŠ” μ½”λ“œλ₯Ό 인수둜 λ„˜κ²¨μ€„ 수 있고 Predicate λŠ” κ·Έ μ˜ˆμ‹œμ΄λ‹€.

Predicate λŠ” μˆ˜ν•™μ—μ„œ 인수둜 값을 λ°›μ•„ true λ‚˜ false λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.

1.3.3 λ©”μ„œλ“œ μ „λ‹¬μ—μ„œ λžŒλ‹€λ‘œ

ν•œ 번만 μ‚¬μš©ν•  λ©”μ„œλ“œλŠ” λ”°λ‘œ μ •μ˜λ₯Ό κ΅¬ν˜„ν•  ν•„μš”κ°€ μ—†λ‹€.

이 λ•Œ, λžŒλ‹€λ₯Ό μ‚¬μš©ν•˜μ—¬ κ°„λ‹¨νžˆ ν•΄κ²°ν•  수 μžˆλ‹€.

λ‹€λ§Œ λžŒλ‹€κ°€ λͺ‡ 쀄 μ΄μƒμœΌλ‘œ 길어진닀면 이 μ½”λ“œκ°€ μˆ˜ν–‰ν•˜λŠ” 일을 잘 μ„€λͺ…ν•˜λŠ” λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜κ³  λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 λ°”λžŒμ§ν•˜λ‹€.

1.4 슀트림

거의 λͺ¨λ“  μžλ°” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ»¬λ ‰μ…˜μ„ λ§Œλ“€κ³  ν™œμš©ν•œλ‹€.

예λ₯Ό λ“€μ–΄ λ¦¬μŠ€νŠΈμ—μ„œ κ³ κ°€μ˜ 거래만 ν•„ν„°λ§ν•œ λ‹€μŒ ν†΅ν™”λ‘œ κ²°κ³Όλ₯Ό κ·Έλ£Ήν•‘ν•΄μ•Ό ν•œλ‹€κ³  ν•˜μž.

μ½”λ“œλ₯Ό ν•œ λ²ˆμ— μ΄ν•΄ν•˜κΈ° μ–΄λ ΅λ‹€.

슀트림 API λ₯Ό μ΄μš©ν•˜λ©΄ ν•΄κ²°ν•  수 μžˆλ‹€.

  • μ™ΈλΆ€ 반볡 : μ»¬λ ‰μ…˜μ—μ„œλŠ” for-each 루프λ₯Ό μ΄μš©ν•˜μ—¬ 각 μš”μ†Œλ₯Ό λ°˜λ³΅ν•˜λ©° μž‘μ—…μ„ μˆ˜ν–‰ν–ˆλ‹€.
  • λ‚΄λΆ€ 반볡 : 슀트림 API μ—μ„œλŠ” 라이브러리 λ‚΄λΆ€μ—μ„œ λͺ¨λ“  데이터가 μ²˜λ¦¬λœλ‹€.

1.4.1 λ©€ν‹°μŠ€λ ˆλ”©μ€ μ–΄λ ΅λ‹€

λ©€ν‹°μŠ€λ ˆλ”© ν™˜κ²½μ—μ„œ 각각의 μŠ€λ ˆλ“œλŠ” λ™μ‹œμ— 곡유된 데이터에 μ ‘κ·Όν•˜κ³  데이터λ₯Ό κ°±μ‹ ν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ μŠ€λ ˆλ“œλ₯Ό 잘λͺ» μ œμ–΄ν•˜λ©΄ μ›μΉ˜ μ•Šμ€ λ°©μ‹μœΌλ‘œ 데이터가 λ°”λ€” 수 μžˆλ‹€.

μžλ°” 8은 μŠ€νŠΈλ¦Όμ—μ„œ λ©€ν‹°μ½”μ–΄ ν™œμš© 어렀움에 λŒ€ν•œ 문제λ₯Ό λ˜ν•œ ν•΄κ²°ν–ˆλ‹€.

  1. 데이터λ₯Ό 뢄리해 ν•˜λ‚˜μ˜ CPU λŠ” μ•žλΆ€λΆ„, λ‹€λ₯Έ CPU λŠ” λ’· 뢀뢄을 μ²˜λ¦¬ν•˜λ„λ‘ ν•œλ‹€. 이λ₯Ό 포킹 단계라고 ν•œλ‹€.
  2. 각 CPUκ°€ 데이터λ₯Ό μ²˜λ¦¬ν•œλ‹€.
  3. κ²°κ³Όλ₯Ό ν•˜λ‚˜λ‘œ μ •λ¦¬ν•œλ‹€.

parallelStream 으둜 병렬 처리λ₯Ό μš”μ²­ν•  수 μžˆλ‹€.

1.5 λ””ν΄νŠΈ λ©”μ„œλ“œμ™€ μžλ°” λͺ¨λ“ˆ

μžλ°” 8μ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‰½κ²Œ λ°”κΏ€ 수 μžˆλ„λ‘ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ§€μ›ν•œλ‹€.

μžλ°” 8 μ΄μ „μ—λŠ” List κ°€ Stream μ΄λ‚˜ parallelStream λ©”μ„œλ“œλ₯Ό μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.

즉 바뀐 μžλ°” 8μ—μ„œλŠ” 이전 μ½”λ“œμ— Stream 을 μΆ”κ°€ν•˜μ—¬ 컴파일 ν•  μˆ˜κ°€ μ—†λ‹€.

이미 μ»¬λ ‰μ…˜ API의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” λ§Žμ€ μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬κ°€ μ‘΄μž¬ν•˜λŠ” 것도 λ¬Έμ œλ‹€.

κ·Έλž˜μ„œ κ΅¬ν˜„ ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” λ©”μ„œλ“œλ₯Ό μΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€ν•˜λŠ” κΈ°λŠ₯을 μΆ”κ°€ν–ˆλ‹€.

λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³ λ„ μ›λž˜μ˜ μΈν„°νŽ˜μ΄μŠ€ 섀계λ₯Ό 자유둭게 ν™•μž₯ν•œλ‹€.

μžλ°” 8μ—μ„œλŠ” List μ—μ„œ 직접 sort λ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

μ΄λŸ¬ν•œ default λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

1.6 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œ κ°€μ Έμ˜¨ λ‹€λ₯Έ μœ μš©ν•œ 아이디어

μžλ°” 8μ—μ„œλŠ” NPEλ₯Ό νšŒν”Όν•  수 있게 λ„μ™€μ£ΌλŠ” Optional 클래슀λ₯Ό μ œκ³΅ν•œλ‹€.

Optional 은 값이 μ—†λŠ” 상황을 μ–΄λ–»κ²Œ μ²˜λ¦¬ν• μ§€ λͺ…μ‹œμ μœΌλ‘œ κ΅¬ν˜„ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€.

This post is licensed under CC BY 4.0 by the author.