item 62 . - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

μ•„μ΄ν…œ62 λ‹€λ₯Έ νƒ€μž…μ΄ μ μ ˆν•˜λ‹€λ©΄ λ¬Έμžμ—΄ μ‚¬μš©μ„ ν”Όν•˜λΌ

  • λ¬Έμžμ—΄μ€ λ‹€λ₯Έ κ°’ νƒ€μž…μ„ λŒ€μ‹ ν•˜κΈ°μ— μ ν•©ν•˜μ§€ μ•Šλ‹€.
  • 받은 데이터가 μˆ˜μΉ˜ν˜•μ΄λΌλ©΄ int, float, BigInteger λ“± μ λ‹Ήν•œ 수치 νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•΄μ•Ό ν•œλ‹€. β€˜μ˜ˆ/μ•„λ‹ˆμ˜€β€™ 질문의 닡이라면 μ μ ˆν•œ μ—΄κ±° νƒ€μž…μ΄λ‚˜ boolean으둜 λ³€ν™˜ν•΄μ•Ό ν•œλ‹€. μΌλ°˜ν™”ν•΄ μ΄μ•ΌκΈ°ν•˜μžλ©΄, κΈ°λ³Έ νƒ€μž…μ΄λ“  μ°Έμ‘° νƒ€μž… 이든 μ μ ˆν•œ κ°’ νƒ€μž…μ΄ μžˆλ‹€λ©΄ 그것을 μ‚¬μš©ν•˜κ³ , μ—†λ‹€λ©΄ μƒˆλ‘œ ν•˜λ‚˜ μž‘μ„±ν•˜λΌ.

1. λ¬Έμžμ—΄μ€(μƒμˆ˜) μ—΄κ±° νƒ€μž…μ„ λŒ€μ‹ ν•˜κΈ°μ— μ ν•©ν•˜μ§€ μ•Šλ‹€.

  • λ¬Έμžμ—΄ μ˜€νƒ€λŠ” μ»΄νŒŒμΌλŸ¬κ°€ 체크해쀄 수 μ—†λ‹€.
  • λ¬Έμžμ—΄μ€ 쀑볡을 κ³ λ―Όν•΄μ•Ό ν•œλ‹€. (ex λ„€μž„μŠ€νŽ˜μ΄μŠ€ 역할을 ν•˜λŠ” 접두사 뢙이기)
  • λ¬Έμžμ—΄ μƒμˆ˜λŠ” μ „λΆ€λ₯Ό μˆœνšŒν•  방법이 μ—†λ‹€. (ex_ values())

2. λ¬Έμžμ—΄μ€ ν˜Όν•© νƒ€μž…μ„ λŒ€μ‹ ν•˜κΈ°μ— μ ν•©ν•˜μ§€ μ•Šλ‹€.

String compoundKey = className + "#" + i.next();
  • 각 μš”μ†Œμ˜ κ΅¬λΆ„μžκ°€ μ—¬λŸ¬ μ’…λ₯˜μΈ 경우 ν˜Όλž€μ„ μ΄ˆλž˜ν•œλ‹€.
  • 각 μš”μ†Œλ₯Ό μ–»μœΌλ €λ©΄ νŒŒμ‹±ν•΄μ•Ό ν•œλ‹€.

3. λ¬Έμžμ—΄μ€ κΆŒν•œμ„ ν‘œν˜„ν•˜κΈ°μ— μ ν•©ν•˜μ§€ μ•Šλ‹€

  • 예λ₯Ό λ“€μ–΄ μŠ€λ ˆλ“œ μ§€μ—­λ³€μˆ˜ κΈ°λŠ₯을 μ„€κ³„ν•œλ‹€κ³  ν•΄λ³΄μž. κ·Έ μ΄λ¦„μ²˜λŸΌ 각 μŠ€λ ˆλ“œκ°€ μžμ‹ λ§Œμ˜ λ³€μˆ˜λ₯Ό κ°–κ²Œ ν•΄μ£ΌλŠ” κΈ°λŠ₯이닀. λ°”λ‘œ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ œκ³΅ν•œ λ¬Έμžμ—΄ ν‚€λ‘œ μŠ€λ ˆλ“œλ³„ μ§€μ—­λ³€μˆ˜λ₯Ό μ‹λ³„ν•œ 것이닀.
public class ThreadLocal {
    private ThreadLocal() { } // 객체 생성 λΆˆκ°€
    // ν˜„ μŠ€λ ˆλ“œμ˜ 값을 ν‚€λ‘œ ꡬ뢄해 μ €μž₯ν•œλ‹€.
    public static void set(String key, Object value);
    // (ν‚€κ°€ κ°€λ¦¬ν‚€λŠ”) ν˜„ μŠ€λ ˆλ“œμ˜ 값을 λ°˜ν™˜ν•œλ‹€.
    public static Object get(String key);
}
  • 이 λ°©μ‹μ˜ λ¬Έμ œλŠ” μŠ€λ ˆλ“œ κ΅¬λΆ„μš© λ¬Έμžμ—΄ ν‚€κ°€ μ „μ—­ μ΄λ¦„κ³΅κ°„μ—μ„œ κ³΅μœ λœλ‹€λŠ” 점이닀. 이 방식이 μ˜λ„λŒ€λ‘œ λ™μž‘ν•˜λ €λ©΄ 각 ν΄λΌμ΄μ–ΈνŠΈκ°€ κ³ μœ ν•œ ν‚€λ₯Ό μ œκ³΅ν•΄μ•Ό ν•œλ‹€.
  • 그런데 λ§Œμ•½ 두 ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ‘œ μ†Œν†΅ν•˜μ§€ λͺ»ν•΄ 같은 ν‚€λ₯Ό μ“°κΈ°λ‘œ κ²°μ •ν•œλ‹€λ©΄, μ˜λ„μΉ˜ μ•Šκ²Œ 같은 λ³€μˆ˜λ₯Ό κ³΅μœ ν•˜κ²Œ λœλ‹€. κ²°κ΅­ 두 ν΄λΌμ΄μ–ΈνŠΈ λͺ¨λ‘ μ œλŒ€λ‘œ κΈ°λŠ₯ν•˜μ§€ λͺ»ν•  것이닀. λ³΄μ•ˆλ„ μ·¨μ•½ν•˜λ‹€. μ•…μ˜μ μΈ ν΄λΌμ΄μ–ΈνŠΈλΌλ©΄ μ˜λ„μ μœΌλ‘œ 같은 ν‚€λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€λ₯Έ ν΄λΌμ΄μ–ΈνŠΈμ˜ 값을 κ°€μ Έμ˜¬ μˆ˜λ„ μžˆλ‹€.
public class ThreadLocal {
    private ThreadLocal() { } // 객체 생성 λΆˆκ°€
    public static class Key { // (κΆŒν•œ)
        Key() { }
    }
    // μœ„μ‘° λΆˆκ°€λŠ₯ν•œ 고유 ν‚€λ₯Ό μƒμ„±ν•œλ‹€.
    public static Key getKey() {
        return new Key();
    }
    public static void set(Key key, Object value);
    public static Object get(Key key);
}
  • 이 APIλŠ” λ¬Έμžμ—΄ λŒ€μ‹  μœ„μ‘°ν•  수 μ—†λŠ” ν‚€λ₯Ό μ‚¬μš©ν•˜λ©΄ ν•΄κ²°λœλ‹€. 이 ν‚€λ₯Ό κΆŒν•œ (capacity)이라고도 ν•œλ‹€.
  • setκ³Ό get은 이제 정적 λ©”μ„œλ“œμΌ μ΄μœ κ°€ μ—†μœΌλ‹ˆ Key 클래슀의 μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ‘œ λ°”κΎΈμž. μ΄λ ‡κ²Œ ν•˜λ©΄ KeyλŠ” 더 이상 μŠ€λ ˆλ“œ μ§€μ—­λ³€μˆ˜λ₯Ό κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ ν‚€κ°€ μ•„λ‹ˆλΌ, κ·Έ μžμ²΄κ°€ μŠ€λ ˆλ“œ μ§€μ—­λ³€μˆ˜κ°€ λœλ‹€.
public final class ThreadLocal {
    public ThreadLocal();
    public void set(Object value);
    public Object get();
}
  • 이 APIμ—μ„œλŠ” get으둜 얻은 Objectλ₯Ό μ‹€μ œ νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•΄ 써야 ν•΄μ„œ νƒ€μž… μ•ˆμ „ν•˜μ§€ μ•Šλ‹€.
  • 처음의 λ¬Έμžμ—΄ 기반 APIλŠ” νƒ€μž…μ•ˆμ „ν•˜κ²Œ λ§Œλ“€ 수 μ—†μœΌλ©°, Keyλ₯Ό μ‚¬μš©ν•œ API도 νƒ€μž…μ•ˆμ „ν•˜κ²Œ λ§Œλ“€κΈ° μ–΄λ ΅λ‹€. ν•˜μ§€λ§Œ ThreadLocal을 λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…(μ•„μ΄ν…œ29)으둜 μ„ μ–Έν•˜λ©΄ κ°„λ‹¨ν•˜κ²Œ λ¬Έμ œκ°€ ν•΄κ²°λœλ‹€.
public final class ThreadLocal<T> {
    public ThreadLocal();
    public void set(T value);
    public T get();
}
  • 이제 μžλ°”μ˜ java.lang.ThreadLocalκ³Ό ν‘μ‚¬ν•΄μ‘Œλ‹€. λ¬Έμžμ—΄ 기반 API의 문제λ₯Ό ν•΄κ²°ν•΄μ£Όλ©°, ν‚€ 기반 API보닀 λΉ λ₯΄κ³  μš°μ•„ν•˜λ‹€.

핡심정리

더 μ ν•©ν•œ 데이터 νƒ€μž…μ΄ μžˆκ±°λ‚˜ μƒˆλ‘œ μž‘μ„±ν•  수 μžˆλ‹€λ©΄, λ¬Έμžμ—΄μ„ μ“°κ³  싢은 μœ ν˜Ήμ„ 뿌리쳐라.
λ¬Έμžμ—΄μ€ 잘λͺ» μ‚¬μš©ν•˜λ©΄ 번거둭고, 덜 μœ μ—°ν•˜κ³ , 느리고, 였λ₯˜ κ°€λŠ₯성도 크닀.
λ¬Έμžμ—΄μ„ 잘λͺ» μ‚¬μš©ν•˜λŠ” ν”ν•œ μ˜ˆλ‘œλŠ” κΈ°λ³Έ νƒ€μž…, μ—΄κ±° νƒ€μž…, ν˜Όν•© νƒ€μž…μ΄ μžˆλ‹€.

⚠️ **GitHub.com Fallback** ⚠️