Tech Interview

[Java] μžλ°” ν…Œν¬ 인터뷰 part3

sohyeonnn 2023. 6. 13. 18:08

πŸ‘‰πŸ»Java 8

β—Ό 슀트림Stream API에 λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • Java 8μ—μ„œ λ‚˜μ˜¨ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€, 일련의 element 듀에 λŒ€ν•œ 연산을 순차적, λ˜λŠ” λ³‘λ ¬μ μœΌλ‘œ μ²˜λ¦¬ν•΄ μ€€λ‹€.
  • 데이터 μ†ŒμŠ€μ— λŒ€ν•œ κ³΅ν†΅λœ μ ‘κ·Ό 방식을 μ œκ³΅ν•œλ‹€.
  • μŠ€νŠΈλ¦Όμ€ 원본 데이터λ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • μŠ€νŠΈλ¦Όμ€ μ™ΈλΆ€ λ°˜λ³΅μ„ 톡해 μž‘μ—…ν•˜λŠ” μ»¬λ ‰μ…˜κ³ΌλŠ” 달리 λ‚΄λΆ€ 반볡(internal iteration)을 톡해 μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.
  • μŠ€νŠΈλ¦Όμ€ μž¬μ‚¬μš©μ΄ κ°€λŠ₯ν•œ μ»¬λ ‰μ…˜κ³ΌλŠ” 달리 단 ν•œ 번만 μ‚¬μš©ν•  수 μžˆλ‹€.
  • 슀트림의 연산은 ν•„ν„°(filter)-λ§΅(map) 기반의 APIλ₯Ό μ‚¬μš©ν•˜μ—¬ μ§€μ—°(lazy) 연산을 톡해 μ„±λŠ₯을 μ΅œμ ν™”ν•œλ‹€.
  • μŠ€νŠΈλ¦Όμ€ parallelStream() λ©”μ„œλ“œλ₯Ό ν†΅ν•œ μ†μ‰¬μš΄ λ³‘λ ¬ μ²˜λ¦¬λ₯Ό μ§€μ›ν•œλ‹€.
  • μŠ€νŠΈλ¦Όμ€ [슀트림의 생성 -> 슀트림의 μ€‘κ°œ μ—°μ‚° -> 슀트림의 μ΅œμ’… μ—°μ‚°] 의 μ„Έ κ°€μ§€ 단계에 κ±Έμ³μ„œ λ™μž‘ν•˜λ©°, μ€‘κ°œ μ—°μ‚°μ˜ 경우 Streamν˜•νƒœλ‘œ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— μ—°μ†μ μœΌλ‘œ μ—°κ²°ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

β—Ό 슀트림이 λ‚˜μ˜€κ²Œλœ μ΄μœ λŠ”?

  • μžλ°”μ—μ„œ λ°°μ—΄μ΄λ‚˜ μ»¬λ ‰μ…˜μ„ μ‚¬μš©ν•  λ•Œ 여기에 μ €μž₯된 데이터에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄μ„œλŠ” λ°˜λ³΅λ¬Έμ΄λ‚˜ 반볡자(Iterator)λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터에 μ ‘κ·Όν•΄μ•Όν–ˆλŠ”λ°, κ·Έλ ‡κ²Œ 되면 μ½”λ“œκ°€ λ„ˆλ¬΄ κΈΈμ–΄μ§€κ³  가독성도 λ–¨μ–΄μ§€κ³ , μ½”λ“œμ˜ μž¬μ‚¬μš©μ΄ 거의 λΆˆκ°€λŠ₯ν•œ μƒνƒœμ˜ μ½”λ“œκ°€ νƒ„μƒν•œλ‹€. μ΄λŸ¬ν•œ λ¬Έμ œμ μ„ κ·Ήλ³΅ν•˜κΈ° μœ„ν•΄ 슀트림이 λ“±μž₯ν–ˆλ‹€.

β—Ό 일반적인 for-loop 보닀 슀트림의 for-eachκ°€ 느린이유λ₯Ό μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • μ΅œμ ν™”λ¬Έμ œ
    Stream의 경우 비ꡐ적 μ΅œκ·Όμ— λ‚˜μ˜¨ κΈ°λŠ₯이기 λ•Œλ¬Έμ— Stream에 λŒ€ν•΄μ„  μΆ©λΆ„ν•œ μ΅œμ ν™”κ°€ μ§„ν–‰λ˜μ§€ μ•Šμ•˜μ„ κ²ƒμ΄λΌλŠ” μΆ”μΈ‘
  • for문은 λ‹¨μˆœ 인덱슀 기반
    for문은 λ‹¨μˆœ μΈλ±μŠ€ κΈ°λ°˜μœΌλ‘œ λ„λŠ” λ°˜λ³΅λ¬ΈμœΌλ‘œ λ©”λͺ¨λ¦¬ μ ‘근이기 λ•Œλ¬Έμ— Stream에 λΉ„ν•΄ λΉ λ₯΄κ³  μ˜€λ²„ν—€λ“œλ„ μ—†λ‹€.
    stream의 κ²½μš°λŠ” JVM이 μ²˜λ¦¬ν•΄μ€˜μ•Όν•˜λŠ” 것듀이 λ§Žμ•„ μ‹€ν–‰ μ‹œ 느릴 수 밖에 μ—†λ‹€.

β—Ό ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ—λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λž€ 1 개의 좔상 λ©”μ†Œλ“œλ₯Ό κ°–λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§ν•œλ‹€.
    ➑ 좔상 λ©”μ„œλ“œκ°€ ν•˜λ‚˜λΌλŠ” λœ»μ€ default method λ˜λŠ” static method λŠ” μ—¬λŸ¬ 개 μ‘΄μž¬ν•΄λ„ 상관 μ—†λ‹€λŠ” λœ»μž…λ‹ˆλ‹€.
  • Java8 λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€λŠ” κΈ°λ³Έ κ΅¬ν˜„μ²΄λ₯Ό ν¬ν•¨ν•œ λ””ν΄νŠΈ λ©”μ„œλ“œ (default method) λ₯Ό 포함할 수 μžˆλ‹€.
  • μ—¬λŸ¬ 개의 λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μžˆλ”λΌλ„ 좔상 λ©”μ„œλ“œκ°€ 였직 ν•˜λ‚˜λ©΄ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.
  • μžλ°”μ˜ λžŒλ‹€ ν‘œν˜„μ‹μ€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œλ§Œ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
  • @FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λŠ”λ°, 이 μ–΄λ…Έν…Œμ΄μ…˜μ€ ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€κ°€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ 쑰건에 λ§žλŠ”μ§€ 검사해쀀닀.
  • @FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ΄ 없어도 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œ λ™μž‘ν•˜κ³  μ‚¬μš©ν•˜λŠ” 데 λ¬Έμ œλŠ” μ—†μ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€ 검증과 μœ μ§€λ³΄μˆ˜λ₯Ό μœ„ν•΄ λΆ™μ—¬μ£ΌλŠ” 게 μ’‹λ‹€.

β—Ό Javaμ—μ„œ κΈ°λ³Έ μ œκ³΅ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ—λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

//κΈ°λ³Έ μ˜ˆμ‹œ νƒ€μž…
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}
  • Predicate
    Predicate ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” T νƒ€μž…μ˜ μΈμžλ₯Ό λ°›μ•„ boolean κ°’을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    ➑ boolean test(T t);
  • Consumer
    μ΄λ¦„μ—μ„œ μ•Œ μˆ˜ μžˆλ“―이 Consumer ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” λ°μ΄ν„°λ§Œ μ†ŒλΉ„ν•˜κ³  μ•„무것도 μƒμ„±ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. T νƒ€μž…μ˜ μΈμžμ— λŒ€ν•΄ λͺ¨λ“  μž‘업을 μˆ˜ν–‰ν•  μˆ˜ μžˆμœΌλ©°, λ°˜ν™˜ νƒ€μž…은 voidμž…λ‹ˆλ‹€. 
    ➑ void accept(T t);
  • Supplier
    Supplier ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” λ§€κ°œλ³€μˆ˜κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©°, κ³΅κΈ‰μžλΌλŠ” μ΄λ¦„μ²˜λŸΌ 아무것도 λ°›μ§€ μ•Šκ³  T νƒ€μž…μ˜ 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    ➑ T get();
  • Function
    Function ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” T νƒ€μž…μ˜ 인자λ₯Ό λ°›μ•„ νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ ν›„ R νƒ€μž…μ˜ 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    μˆ˜ν•™μ‹μ—μ„œμ˜ ν•¨μˆ˜μ²˜λŸΌ νŠΉμ • 값을 λ°›μ•„μ„œ λ‹€λ₯Έ κ°’μœΌλ‘œ λ°˜ν™˜ν•΄μ£Όλ©°, T 와 R 은 같은 νƒ€μž…μ„ μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
    Consumer와 Supplier의 μ‘°ν•©μž…λ‹ˆλ‹€.
    ➑ R apply(T t);
  • Runnable
    Runnable ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜ νƒ€μž…이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. run() λ©”μ„œλ“œμ— μ •μ˜λœ μ½”λ“œλ§Œ μ‹€ν–‰ν•©λ‹ˆλ‹€.
    Runnable μ΄λΌλŠ” μ΄λ¦„에 λ§žκ²Œ "μ‹€ν–‰ κ°€λŠ₯ν•œ" μ΄λΌλŠ” λœ»μ„ λ‚˜νƒ€λ‚΄λ©° μ΄λ¦„ κ·ΈλŒ€λ‘œ μ‹€ν–‰λ§Œ ν•  μˆ˜ μžˆλ‹€κ³  μƒκ°ν•˜λ©΄ λ©λ‹ˆλ‹€.

β—Ό Optional μ—λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • Java8μ—μ„œλŠ” Optional<T> ν΄λž˜μŠ€λ₯Ό μ‚¬μš©ν•΄ NPE(NullPointerException)λ₯Ό λ°©μ§€ν•  μˆ˜ μžˆλ„둝 λ„와쀀닀. 
  • Optional<T>λŠ” null이 μ˜¬ μˆ˜ μžˆλŠ” κ°’을 κ°μ‹ΈλŠ” Wrapper ν΄λž˜μŠ€λ‘œ, μ°Έμ‘°ν•˜λ”라도 NPEκ°€ λ°œμƒν•˜μ§€ μ•Šλ„둝 λ„와쀀닀. Optional ν΄λž˜μŠ€λŠ” μ•„λž˜μ™€ κ°™μ€ value에 κ°’을 μ €μž₯ν•˜κΈ° λ•Œλ¬Έμ— κ°’이 null이더라도 λ°”λ‘œ NPEκ°€ λ°œμƒν•˜μ§€ μ•ŠμœΌλ©°, ν΄λž˜μŠ€μ΄κΈ° λ•Œλ¬Έμ— κ°μ’… λ©”μ†Œλ“œλ₯Ό μ œκ³΅ν•΄μ€€λ‹€.

➑ 즉, Optional은 null λ˜λŠ” 값을 κ°μ‹Έμ„œ NPE(NullPointerException)λ‘œλΆ€ν„° 뢀담을 쀄이기 μœ„ν•΄ λ“±μž₯ν•œ Wrapper ν΄λž˜μŠ€μ΄λ‹€.


πŸ‘‰πŸ»Modifier

β—Ό μ œμ–΄μžλž€(modifier) ?

λ³€μˆ˜, λ©”μ†Œλ“œ, ν΄λž˜μŠ€ μ„ μ–ΈλΆ€μ— ν‘œμ‹œλ˜μ–΄ λΆ€κ°€μ μΈ μ˜λ―Έλ₯Ό λΆ€μ—¬ν•˜λŠ” ν‚€μ›Œλ“œλ₯Ό λ§ν•œλ‹€. μ œμ–΄μžλŠ” μ ‘κ·Ό μ œμ–΄μžμ™€ κ·Έ μ™Έμ˜ μ œμ–΄μž, 두 κ°€μ§€ μ’…λ₯˜λ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.

  • μ ‘κ·Όμ œμ–΄μžλž€
    λ³€μˆ˜ λ˜λŠ” λ©”λͺ¨λ¦¬ μ ‘κ·Ό λ²”μœ„λ₯Ό μ„€μ •ν•΄μ£ΌκΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” Java의 μ˜ˆμ•½μ–΄λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. 총 4κ°€μ§€ μ’…λ₯˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.
    μ ‘κ·Ό μ œμ–΄μžλŠ” ν•œ λ²ˆμ— λ„€ κ°€μ§€ 쀑 ν•˜λ‚˜λ§Œ μ„ νƒν•΄μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • public은 μ ‘κ·Ό μ œν•œμ΄ μ—†μœΌλ―€λ‘œ, 같은 ν”„λ‘œμ νŠΈ λ‚΄ μ–΄λ””μ„œλ“  μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.
    • protectedλŠ” ν•΄λ‹Ή νŒ¨ν‚€μ§€ λ‚΄, λ‹€λ₯Έ νŒ¨ν‚€μ§€μ—μ„œ 상속받아 μžμ† ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.
    • defaultλŠ” ν•΄λ‹Ή νŒ¨ν‚€μ§€ λ‚΄μ—μ„œλ§Œ 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.
    • privateλŠ” ν•΄λ‹Ή 클래슀 λ‚΄μ—μ„œλ§Œ 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • κ·Έμ™Έμ˜ μ œμ–΄μž
    • static은 클래슀의, κ³΅ν†΅μ μΈμ˜ 의미λ₯Ό κ°€μ§€κ³  μžˆλ‹€. static이 뢙은 λ©€λ²„λ³€μˆ˜μ™€ λ©”μˆ˜λ“œ, μ΄ˆκΈ°ν™” λΈ”λŸ­μ€ μΈμŠ€ν„΄μŠ€κ°€ μ•„λ‹Œ ν΄λž˜μŠ€μ— κ΄€κ³„λœ 것이기 λ•Œλ¬Έμ—, μΈμŠ€ν„΄μŠ€ 생성 여뢀와 관계 없이 μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.
    • final은 λ§ˆμ§€λ§‰μ˜, λ³€κ²½λ  μˆ˜ μ—†λŠ” μ˜λ―Έλ₯Ό κ°€μ§€κ³  μžˆκ³ , κ±°μ˜ λͺ¨λ“  λŒ€μƒμ— μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.
    • abstract은 μΆ”μƒμ˜, λ―Έμ™„μ„±μ˜ 의미λ₯Ό κ°€μ§€κ³  μžˆλ‹€. λ©”μ„œλ“œμ˜ μ„ μ–ΈλΆ€μ—λ§Œ μž‘μ„±ν•˜κ³ , μ‹€μ œ μˆ˜ν–‰λ‚΄μš©μ€ κ΅¬ν˜„ν•˜μ§€ μ•Šμ€ 좔상 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•˜λŠ”λ° μ‚¬μš©λœλ‹€

β—Ό λ©”μ†Œλ“œ parameter 에 final 에 λΆ™μ΄λŠ” 경우λ₯Ό μ–΄λ–»κ²Œ μƒκ°ν•˜μ‹œλŠ”μ§€ μ„€λͺ…ν•΄μ£Όμ„Έμš”

  • λΆˆλ³€ μ„±μ§ˆμ„ κ°•μ‘°ν•˜λ €λŠ” 경우 final ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬ 이 λ§€κ°œλ³€μˆ˜μ˜ 값이 λ©”μ†Œλ“œ λ‚΄μ—μ„œ λ³€κ²½λ˜μ§€ μ•Šμ•„μ•Ό 함을 λͺ…μ‹œμ μœΌλ‘œ 보μž₯ν•˜κ³ μž ν•˜λŠ” μ˜λ„λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ, final ν‚€μ›Œλ“œλ₯Ό λ„ˆλ¬΄ λ‚¨λ°œν•˜λ©΄ μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§€κ³  가독성이 λ–¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ λ©”μ†Œλ“œμ˜ 둜직이 λ³΅μž‘ν•΄μ§€μ§€ μ•ŠλŠ”λ‹€λ©΄, 일반적으둜 λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜μ— final을 ꡳ이 뢙이지 μ•ŠλŠ” 것이 μΌλ°˜μ μž…λ‹ˆλ‹€.
  • μ˜€λ²„λΌμ΄λ”©μ΄ λΆˆκ°€ν•˜κ³  μ˜€λ²„λ‘œλ”©λ§Œ κ°€λŠ₯ν•΄μ§„λ‹€.

πŸ‘‰πŸ»Synchronization

β—Ό 동기화(synchronization) λž€?

μ—¬λŸ¬ 개의 μ“°λ ˆλ“œκ°€ ν•œ 개의 μžμ›μ„ μ‚¬μš©ν•˜κ³ μž ν•  λ•Œ, ν˜„μž¬ 데이터λ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ” μ“°λ ˆλ“œλ₯Ό μ œμ™Έν•˜κ³  λ‚˜λ¨Έμ§€ μ“°λ ˆλ“œλ“€μ€ 데이터에 μ ‘κ·Όν•  수 μ—†κ²Œ λ§‰λŠ” κ°œλ…μž…λ‹ˆλ‹€.

  • λ©€ν‹°μŠ€λ ˆλ“œ μ ‘κ·Ό μ œν•œ ν‚€μ›Œλ“œ 이닀.
  • λ©”μ†Œλ“œ λ‹¨μœ„, 블둝 λ‹¨μœ„ 적용 κ°€λŠ₯ν•˜λ‹€.
  • 단, μž„κ³„μ˜μ—­μ΄ μž‘μ„μˆ˜λ‘ μ’‹κΈ° λ•Œλ¬Έμ— 블둝 λ‹¨μœ„μ˜ μ‚¬μš©μ„ ꢌμž₯ν•œλ‹€.

β—Ό synchronized λ₯Ό μ‚¬μš©ν•  μ‹œ sychronized method, sychronized block, static sychronized method, static synchonized block 의 4κ°€μ§€ μ“°μž„μƒˆ κ²½μš°μ— λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • sychronized method
    • 클래슀 μΈμŠ€ν„΄μŠ€ μ— lock을 κ²λ‹ˆλ‹€.
    • μΈμŠ€ν„΄μŠ€μ— lock을 κ±°λŠ” synchronized ν‚€μ›Œλ“œλŠ” synchronizedκ°€ 적용된 λ©”μ„œλ“œλΌλ¦¬ μΌκ΄„μ μœΌλ‘œ lock을 κ³΅μœ ν•©λ‹ˆλ‹€.
  • static sychronized method
    • static이 뢙은 synchronized methodλŠ” 일반적으둜 μƒκ°ν•˜λŠ” static μ„±μ§ˆμ„ κ°–μœΌλ―€λ‘œ μΈμŠ€ν„΄μŠ€κ°€ μ•„λ‹Œ ν΄λž˜μŠ€ λ‹¨μœ„ λ‘œ lock을 κ²λ‹ˆλ‹€.
    • λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€λ”λΌλ„ static λ©”μ„œλ“œμ— synchronizedκ°€ 뢙은 경우 lock을 κ³΅μœ ν•˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
    •  static synchronized method와 synchronized method의 lock은 κ³΅μœ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • sychronized block
    • μΈμŠ€ν„΄μŠ€μ˜ block λ‹¨μœ„ λ‘œ lock을 κ±Έκ³  lock 객체λ₯Ό μ§€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    • block에 thisλ₯Ό λͺ…μ‹œν•  경우 method에 synchornizedλ₯Ό 뢙인 κ²ƒμ²˜λŸΌ μΈμŠ€ν„΄μŠ€ λ‹¨μœ„λ‘œ lock이 κ±Έλ¦½λ‹ˆλ‹€.
    • blockμ—λŠ” 객체λ₯Ό μ§€μ •ν•  μˆ˜λ„ 있고 class ν˜•μ‹μœΌλ‘œ λ„˜κΈ°λ©΄ ν•΄λ‹Ή class에 lock을 κ±Έ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • static synchonized block 
    • this와 같이 ν˜„μž¬ 객체λ₯Ό κ°€λ₯΄ν‚€λŠ” ν‘œν˜„μ€ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
    • static synchronized method λ°©μ‹κ³Όμ˜ μ°¨μ΄λŠ” lock 객체λ₯Ό μ§€μ •ν•˜κ³  block λ²”μœ„λ₯Ό ν•œμ • 지을 수 μžˆλ‹€λŠ” μ μž…λ‹ˆλ‹€. 클래슀 λ‹¨μœ„λ‘œ lock을 κ³΅μœ ν•œλ‹€λŠ” 점은 κ°™μŠ΅λ‹ˆλ‹€.
    • block의 인자둜 정적 μΈμŠ€ν„΄μŠ€λ‚˜ 클래슀만 μ‚¬μš©ν•©λ‹ˆλ‹€.

β—Ό synchronized μ‚¬μš© μ‹œ λ°λ“œλ½μ΄ λ°œμƒν•˜λŠ” 상황을 μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • μƒν˜Έ 배제 (Mutual Exclusion) : ν•œ μžμ›μ— λŒ€ν•΄ μ—¬λŸ¬ μ“°λ ˆλ“œ λ™μ‹œ μ ‘κ·Ό λΆˆκ°€
  • μ μœ μ™€ λŒ€κΈ° (Hold and Wait) : μžμ›μ„ κ°€μ§€κ³  μžˆλŠ” μƒνƒœμ—μ„œ λ‹€λ₯Έ μ“°λ ˆλ“œκ°€ μ‚¬μš©ν•˜κ³  μžˆλŠ” μžμ› λ°˜λ‚©μ„ κΈ°λ‹€λ¦¬λŠ” 것
  • 비선점 (Non Preemptive) : λ‹€λ₯Έ μ“°λ ˆλ“œμ˜ μžμ›μ„ μ‹€ν–‰ 쀑간에 κ°•μ œλ‘œ κ°€μ Έμ˜¬ 수 μ—†μŒ
  • ν™˜ν˜•λŒ€κΈ° (Circle Wait) : 각 μ“°λ ˆλ“œκ°€ μˆœν™˜μ μœΌλ‘œ λ‹€μŒ μ“°λ ˆλ“œκ°€ μš”κ΅¬ν•˜λŠ” μžμ›μ„ κ°€μ§€κ³  μžˆλŠ” 것

μœ„μ˜ 4κ°€μ§€ 쑰건을 λͺ¨λ‘ μΆ©μ‘±ν•  경우 λ°λ“œλ½μ΄ λ°œμƒν•˜μ—¬ μ•„λ¬΄λŸ° μ‹€ν–‰ν•˜μ§€ λͺ»ν•œ 채 λ¬΄ν•œμ • λŒ€κΈ°ν•˜κ²Œ λ©λ‹ˆλ‹€. 

β—Ό volatile ν‚€μ›Œλ“œμ— λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

동기화 문제 λ°©μ§€λ₯Ό μœ„ν•΄ volatileν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

λ³€μˆ˜λ₯Ό volatile둜 μ„ μ–Έν•˜λ©΄ 메인 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μ°Έμ‘°ν•˜κ²Œ λ˜λ―€λ‘œ λ‹€λ₯Έ μŠ€λ ˆλ“œλΌλ„ 같은 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό μ°Έμ‘°ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

νŠΉμ§•μ€ μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

  • volatile둜 μ„ μ–Έλœ λ³€μˆ˜κ°€ μžˆλŠ” μ½”λ“œλŠ” μ΅œμ ν™”λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • volatile ν‚€μ›Œλ“œλŠ” λ³€μˆ˜λ₯Ό 'Main Memory에 μ €μž₯ν•˜κ² λ‹€'라고 λͺ…μ‹œν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
  • λ³€μˆ˜μ˜ 값을 Readν•  λ•Œλ§ˆλ‹€ CPU cache에 μ €μž₯된 값이 μ•„λ‹Œ, Main Memoryμ—μ„œ μ½μŠ΅λ‹ˆλ‹€.

 

β—Ό lock을 μ‚¬μš©ν–ˆμ„ μ‹œμ™€ volatile을 μ‚¬μš©ν•  μ‹œμ—, volatile 단점에 λŒ€ν•΄μ„œ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • Multi Thread ν™˜κ²½μ—μ„œ μ—¬λŸ¬κ°œμ˜ Threadκ°€ writeν•˜λŠ” 상황이라면 race conditionrace을 ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 이럴 κ²½μš°μ—λŠ” synchronizedλ₯Ό μ‚¬μš©ν•˜μ—¬ μ›μžμ„±(atomic)을 보μž₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.

πŸ‘‰πŸ»Thread

β—Ό μžλ°”μ—μ„œ thread λ₯Ό μƒμ„±ν•˜λŠ” 방법과 μ‹€ν–‰ν•˜λŠ” 방법을 μ„€λͺ…ν•΄μ£Όμ„Έμš”.

μžλ°”μ—μ„œ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜λŠ” 방법은 두 κ°€μ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€.

  • Threadλ₯Ό μƒμ†λ°›λŠ” 방법
    1. Thread 클래슀λ₯Ό μƒμ†ν•œ 클래슀 μ •μ˜ν•œλ‹€.
    2. run() λ©”μ†Œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ“œν•˜μ—¬ μŠ€λ ˆλ“œ μ½”λ“œ μž‘μ„±ν•œλ‹€.
    3. μŠ€λ ˆλ“œ 객체λ₯Ό μƒμ„±ν•œλ‹€.
    4. start() λ©”μ†Œλ“œλ‘œ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•œλ‹€.
  • Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법
    1. Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 클래슀λ₯Ό μ •μ˜ν•œλ‹€.
    2. run() λ©”μ†Œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ“œν•˜μ—¬ μŠ€λ ˆλ“œ μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€.
    3. Runnable 객체λ₯Ό μƒμ„±ν•œλ‹€.
    4. Thread 객체λ₯Ό μƒμ„±ν•œλ‹€.
    5. start() λ©”μ†Œλ“œλ‘œ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•œλ‹€.

μžλ°”λŠ” 닀쀑 상속을 ν—ˆμš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— Thread 클래슀λ₯Ό μƒμ†λ°›κ²Œ 되면 λ‹€λ₯Έ 클래슀λ₯Ό μƒμ†λ°›μ„μˆ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μΈν„°νŽ˜μ΄μŠ€μΈ Runnable둜 κ΅¬ν˜„ν•˜λŠ” 방법이 μΌλ°˜μ μž…λ‹ˆλ‹€. λ˜ν•œ μž¬μ‚¬μš©μ„±(reusability)이 λ†’κ³  μ½”λ“œμ˜ 일관성(consistency)을 μœ μ§€ν•  수 있기 λ•Œλ¬Έμ— 보닀 객체지ν–₯적인 방법이닀.

참고둜, μ‚¬μš©μžκ°€ μŠ€λ ˆλ“œ 객체λ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰μš”청을 ν•˜λ”λΌλ„ μŠ€λ ˆλ“œκ°€ μ‹€ν–‰λ˜λŠ” 것은 μ „μ μœΌλ‘œ JVM에 μ˜ν•œ μŠ€μΌ€μ₯΄λŸ¬μ— λ”°λ¦…λ‹ˆλ‹€. μ‚¬μš©μžλŠ” Thread의 μ—¬λŸ¬ λ©”μ†Œλ“œλ“€μ„ ν†΅ν•΄μ„œ JVM에 ν•΄λ‹Ή λͺ…령듀이 μ‹€ν–‰λ˜λ„λ‘ μš”μ²­ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 

 

*μŠ€λ ˆλ“œ Thread λž€?

μŠ€λ ˆλ“œλŠ” ν”„λ‘œμ„ΈμŠ€μ•ˆμ—μ„œ μ‹€μ§ˆμ μœΌλ‘œ μž‘μ—…μ„ μ‹€ν–‰ν•˜λŠ” λ‹¨μœ„λ₯Ό λ§ν•©λ‹ˆλ‹€. μžλ°”μ—μ„œλŠ” JVM(Java Virtual Machine)에 μ˜ν•΄ κ΄€λ¦¬λ©λ‹ˆλ‹€.
ν”„λ‘œμ„ΈμŠ€μ—λŠ” 적어도 ν•œκ°œ μ΄μƒμ˜ μŠ€λ ˆλ“œκ°€ 있으며, Main μŠ€λ ˆλ“œ ν•˜λ‚˜λ‘œ μ‹œμž‘ν•˜μ—¬ μŠ€λ ˆλ“œλ₯Ό μΆ”κ°€ μƒμ„±ν•˜κ²Œ 되면 λ©€ν‹° μŠ€λ ˆλ“œ ν™˜κ²½μ΄ λ©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μŠ€λ ˆλ“œλ“€μ€ ν”„λ‘œμ„ΈμŠ€μ˜ λ¦¬μ†ŒμŠ€λ₯Ό κ³΅μœ ν•˜κΈ° λ•Œλ¬Έμ— 효율적이긴 ν•˜μ§€λ§Œ 잠재적인 λ¬Έμ œμ μ— λ…ΈμΆœλ  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 

β—Ό Thread μ‹€ν–‰ μ‹œ run()으둜 μˆ˜ν–‰ν•  λ•Œμ™€ start()둜 μˆ˜ν–‰ν•  λ•Œμ™€μ˜ 차이λ₯Ό μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • run()
    run()을 ν˜ΈμΆœν•˜λŠ” 것은 λ‹¨μˆœνžˆ ν΄λž˜μŠ€μ— μ„ μ–Έλœ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이닀.
  • start()
    start()λŠ” μƒˆλ‘œμš΄ μ“°λ ˆλ“œκ°€ μž‘μ—…μ„ μ‹€ν–‰ν•˜λŠ”λ° ν•„μš”ν•œ ν˜ΈμΆœμŠ€νƒ(call stack)을 μƒμ„±ν•œ λ‹€μŒμ— run()을 ν˜ΈμΆœν•΄μ„œ μƒμ„±λœ ν˜ΈμΆœμŠ€νƒμ— run()이 첫번째둜 μ˜¬λΌκ°€κ²Œ ν•œλ‹€.

β—Ό μΌλ°˜ λ°©μ‹μ—μ„œ main threadκ°€ μ’…λ£Œλ˜λ©΄ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ’…λ£Œλ  텐데, λ©€ν‹°μŠ€λ ˆλ“œ λ°©μ‹μ—μ„œ main threadλŠ” μ–Έμ œ μ’…λ£Œλ˜λ‚˜μš”?

  • μžλ°” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ main μŠ€λ ˆλ“œκ°€ main() λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄μ„œ μ‹œμž‘λ©λ‹ˆλ‹€. main μŠ€λ ˆλ“œμ˜ 흐름 μ•ˆμ—μ„œ λ©€ν‹° μŠ€λ ˆλ“œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ ν•„μš”μ— 따라 μž‘μ—… μŠ€λ ˆλ“œλ₯Ό λ§Œλ“€μ–΄ λ³‘λ ¬λ‘œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 있게 λ©λ‹ˆλ‹€.
  • μ‹±κΈ€ μŠ€λ ˆλ“œμ˜ 경우, 메인 μŠ€λ ˆλ“œκ°€ μ’…λ£Œλ˜λ©΄ ν”„λ‘œμ„ΈμŠ€λ„ μ’…λ£Œλ˜μ§€λ§Œ, λ©€ν‹° μŠ€λ ˆλ“œλŠ” 메인 μŠ€λ ˆλ“œκ°€ μ’…λ£Œλ˜λ”λΌλ„ μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œκ°€ ν•˜λ‚˜λΌλ„ μžˆλ‹€λ©΄ ν”„λ‘œμ„ΈμŠ€κ°€ 계속 μ‹€ν–‰λ˜κ²Œ λ©λ‹ˆλ‹€. (μŠ€λ ˆλ“œλŠ” λ³‘λ ¬μ μœΌλ‘œ μž‘μ—…ν•˜κΈ° λ•Œλ¬Έ)

결과적으둜, λ©€ν‹° μŠ€λ ˆλ“œμ—μ„œ 메인 μŠ€λ ˆλ“œλŠ” return 을 λ§Œλ‚˜κ±°λ‚˜, main λ©”μ„œλ“œμ˜ 끝이였면 μ’…λ£Œν•˜κ²Œ λœλ‹€.

 

*μ§ˆλ¬Έμ—μ„œ μ›ν•˜λŠ” 닡이 μ•„λ‹Œ 것 같은 λŠλ‚Œμ΄ λ“œλŠ”λ° 더 찾아봐야겠닀..

β—Ό ThreadLocal 에 λŒ€ν•΄μ„œ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  •  ThreadLocal은 ν•œ μ“°λ ˆλ“œμ—μ„œ 읽고 μ“°μ—¬μ§ˆ 수 μžˆλŠ” λ³€μˆ˜λ₯Ό ν• λ‹Ήν•˜μ—¬ μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
  • λ©€ν‹° μ“°λ ˆλ“œ ν™˜κ²½μ—μ„œ 각 μ“°λ ˆλ“œλ§ˆλ‹€ get(), set() λ©”μ„œλ“œλ₯Ό 톡해 λ…λ¦½μ μœΌλ‘œ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ§κ·ΈλŒ€λ‘œ Thread λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” μ§€μ—­λ³€μˆ˜μž…λ‹ˆλ‹€.
  • ThreadLocal의 κΈ°λ³Έ μ‚¬μš©λ²•μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
    1. ThreadLocal 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
    2. ThreadLocal.set() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ ν˜„μž¬ thread의 둜컬 λ³€μˆ˜μ— 값을 μ €μž₯ν•©λ‹ˆλ‹€.
    3. ThreadLocal.get() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ ν˜„μž¬ thread의 둜컬 λ³€μˆ˜κ°’μ„ μ½μ–΄μ˜΅λ‹ˆλ‹€.
    4. ThreadLocal.remove() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ ν˜„μž¬ thread 둜컬 λ³€μˆ˜κ°’μ„ μ‚­μ œν•©λ‹ˆλ‹€.

β—Ό λ©€ν‹°μ“°λ ˆλ“œ ν™˜κ²½μ—μ„œ ThreadLocal 을 μ‚¬μš©ν•  λ•Œ μœ μ˜ν•  점에 λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  • μŠ€λ ˆλ“œ λ‘œμ»¬μ€ μŠ€λ ˆλ“œ ν’€(thread pool)을 μ‚¬μš©ν•˜λŠ” ν™˜κ²½μ—μ„œλŠ” μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μŠ€λ ˆλ“œκ°€ μž¬ν™œμš©λ  수 있기 λ•Œλ¬Έμ— μ‚¬μš©μ΄ 끝났닀면 μŠ€λ ˆλ“œ λ‘œμ»¬μ„ λΉ„μ›Œμ£ΌλŠ” 과정이 ν•„μˆ˜μ μ΄λ‹€. 

πŸ‘‰πŸ»Error & Exception

β—Ό μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν•˜λŠ” 방법에 λŒ€ν•΄ μ„€λͺ…ν•΄ μ£Όμ„Έμš”.

  1. try, catch
    μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„λ•Œ μš°λ¦¬λŠ” try ... catch ... finally λΌλŠ” ν‚€μ›Œλ“œλ‘œ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•  수 μžˆκ±°λ‚˜ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œ 곳으둜 던질 수 μžˆμŠ΅λ‹ˆλ‹€. ν•œ κ°€μ§€ μ€‘μš”ν•œ 점은 μžλ°”μ—μ„œ λͺ¨λ“  μ˜ˆμ™ΈλŠ” Exceptionμ΄λΌλŠ” 클래슀λ₯Ό μƒμ†λ°›μŠ΅λ‹ˆλ‹€.
    • try λΈ”둝 : κ°€μž₯ λ¨Όμ € μ‹€ν–‰λ˜λŠ” μ½”λ“œλ‘œ μ—¬κΈ°μ—μ„œ λ°œμƒν•œ μ˜ˆμ™ΈλŠ” catch λΈ”λ‘μ—μ„œ μ²˜λ¦¬λœλ‹€.
    • catch λΈ”둝 : try λΈ”λ‘μ—μ„œ λ°œμƒν•œ μ˜ˆμ™Έ μ½”λ“œλ‚˜ μ˜ˆμ™Έ κ°μ²΄λ₯Ό μΈμˆ˜λ‘œ μ „달받아 μ²˜λ¦¬ν•œλ‹€.
    • finally 블둝 : μ˜ˆμ™Έμ˜ λ°œμƒ μœ λ¬΄μ— 상관없이 λ§ˆμ§€λ§‰μ— 무쑰건 μ‹€ν–‰λœλ‹€.
  2. throws
    λ§κ·ΈλŒ€λ‘œ μ˜ˆμ™Έλ₯Ό λ˜μ§€λŠ” 것을 λœ»ν•©λ‹ˆλ‹€.
    • μ˜ˆμ™Έλ₯Ό μ—¬κΈ°μ„œ μ²˜λ¦¬ν•˜μ§€ μ•Šμ„ν…Œλ‹ˆ λ‚˜λ₯Ό λΆˆλŸ¬λ‹€κ°€ μ“°λŠ” λ…€μ„μ—κ²Œ μ—λŸ¬ μ²˜λ¦¬λ₯Ό μ „κ°€ν•˜κ² λ‹€λŠ” μ˜λ―Έμ΄λ©° μ½”λ“œλ₯Ό μ§œλŠ” μ‚¬λžŒμ΄ μ΄ μ„ μ–ΈλΆ€λ₯Ό λ³΄κ³  μ–΄λ–€ μ˜ˆμ™Έκ°€ λ°œμƒν•  μˆ˜ μžˆλŠ”μ§€λ„ μ•Œκ²Œ ν•΄μ€λ‹ˆλ‹€.

β—Ό Checked Exception κ³Ό Unchecked Exception 의 transaction μ˜ˆμ™Έ 처리 방식을 μ„€λͺ…ν•΄μ£Όμ„Έμš”.

  1. Checked Exception
    • λͺ…μ‹œμ μœΌλ‘œ μ˜ˆμ™Έ μ²˜λ¦¬λ₯Ό κ°•μ œν•˜κΈ° λ•Œλ¬Έμ— checked exception이라 λΆ€λ₯Έλ‹€.
    • μ΄λŠ” Exception ν΄λž˜μŠ€λ₯Ό μ§μ ‘ μƒμ†ν•˜κ±°λ‚˜ IOException, SQLException κ°™μ€ ν•˜μœ„ ν΄λž˜μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°μ— ν•΄λ‹Ήν•©λ‹ˆλ‹€. 
    • try~catch, throws λ“±μ„ μ‚¬μš©ν•˜μ—¬ μ˜ˆμ™Έλ₯Ό λ˜μ§„λ‹€.
    • μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν•˜μ§€ μ•ŠμœΌλ©΄ IDEμ—μ„œ μ»΄νŒŒμΌμ‹œ μ—λŸ¬λ₯Ό λ±‰λŠ”λ‹€.
    • compile Exception으둜 runtime exception ν•˜μœ„ exception을 μ œμ™Έν•˜κ³  λ§ν•œλ‹€.
  2. Unchecked Exception
    • κ°•μ œν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— UnChecked Exception이라 λΆ€λ₯Έλ‹€.
    • 이 μ˜ˆμ™Έλ“€μ€ λŸ°νƒ€μž„ μ‹œ λ°œμƒν•˜λ©°, ν”„λ‘œκ·Έλž˜λ¨Έμ˜ μ‹€μˆ˜λ‘œ λ‚˜νƒ€λ‚˜λŠ” κ²½μš°μ΄λ‹€.
    • μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν•˜μ§€ μ•Šμ•„도 IDEμ—μ„œ μ—λŸ¬λ₯Ό λ±‰μ§€ μ•ŠλŠ”λ‹€.
    • Runtime Exception으둜 μ‹€ν–‰ μ€‘ λ°œμƒν•˜λŠ” Exception을 λ§ν•œλ‹€.
    • Runtime Exception ν•˜μœ„μ˜ NullPointException, IndexOutOfBoundException 등이 μžˆλ‹€.
    • νŠΈλžœμž­μ…˜μ„ κ·Έλƒ₯rollback
    • check λŠ” rollback μ•ˆμ‹œν‚€κ³  μ»€λ°‹ν•œλ‹€κ³  ν•œλ‹€

β—Ό @Transactional λŠ” μ–΄λ–»κ²Œ κ΅¬ν˜„λ˜λ‚˜μš”?

  • @Transactional을 λ©”μ†Œλ“œ λ˜λŠ” ν΄λž˜μŠ€μ— λͺ…μ‹œν•˜λ©΄,
    AOPλ₯Ό 톡해 Target이 μƒμ†ν•˜κ³  μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€ λ˜λŠ” Target 객체λ₯Ό μƒμ†ν•œ Proxy 객체가 μƒμ„±λ˜λ©°,
    Proxy 객체의 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ Target λ©”μ†Œλ“œ μ „ ν›„λ‘œ νŠΈλžœμž­μ…˜ 처리λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

β—Ό @Transactional 이 λΆ™μ§€ μ•Šμ€ λ©”μ†Œλ“œμ˜ λ‚΄λΆ€μ—μ„œ @Transactional 이 뢙은 λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  μ‹œ, 이 λ‚΄λΆ€ λ©”μ†Œλ“œλ„ @Transactional이 μ μš©λ κΉŒμš”?

  • μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€.
  • λ©”μ„œλ“œ λ‹¨μœ„λ‘œ νŠΈλžœμž­μ…˜μ΄ λ™μž‘ν•˜λŠ”λ°, ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œμ—λ„ νŠΈλžœμž­μ…˜μ΄ λΆ™μ–΄μžˆμ–΄μ•Ό μ μš©λœλ‹€. 내무 λ©”μ†Œλ“œμ—λŠ” ν”„λ‘μ‹œκ°μ²΄κ°€ μ—†μ–΄μ„œ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.

 

 

μ°Έκ³