JavaRush /Java Blog /Random-KO /์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160. Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”. Java์˜ ์Šค์บ๋„ˆ ํด...

์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160. Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”. Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค

Random-KO ๊ทธ๋ฃน์— ๊ฒŒ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

Java ThreadLocal ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ

์ถœ์ฒ˜: Devgenios ์˜ค๋Š˜์€ Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜์ธ ThreadLocal์— ๋Œ€ํ•ด ์•Œ์•„๋ด…๋‹ˆ๋‹ค. ์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160.  Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.  Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค - 1

ThreadLocal์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ThreadLocal ํด๋ž˜์Šค๋Š” ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ฒฉ๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ž์ฒด ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ThreadLocal ์‚ฌ์šฉ ์‚ฌ๋ก€ :
  1. ์Šค๋ ˆ๋“œ ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฉ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ์„ธ์…˜ ๊ด€๋ฆฌ.
  3. ์Šค๋ ˆ๋“œ ํŠธ๋žœ์žญ์…˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

ThreadLocal์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋‚˜์š”?

๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
public static void main(String[] args) {
    //ะกะพะทะดะฐะตะผ ThreadLocal
    ThreadLocal<String> local = new ThreadLocal<>();
    //ะกะพะทะดะฐะตะผ ะฝะพะฒั‹ะน ะบะปะฐัั Random
    Random random = new Random();
    //ะกะพะทะดะฐะตะผ 5 ะฟะพั‚ะพะบะพะฒ
    IntStream.range(0, 5).forEach(a-> new Thread(()-> {
        //ะŸั€ะธัะฒะฐะธะฒะฐะตะผ meaning ะบะฐะถะดะพะผัƒ ะฟะพั‚ะพะบัƒ
        local.set(a+"  "+random.nextInt(100));
        System.out.println("Thread number and its local value  "+ local.get());
    }).start());
}
์œ„ ์ฝ”๋“œ์—์„œ๋Š” ThreadLocal ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  , 5๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , ๊ฐ ์Šค๋ ˆ๋“œ์˜ ThreadLocal ์— ๊ฐ’์„ ํ• ๋‹น ํ•˜๊ณ  ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๋‹ค: ์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160.  Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.  Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค - 2

ํ›„๋“œ ์•„๋ž˜์—๋Š” ๋ฌด์—‡์ด ์žˆ๋‚˜์š”?

์ž์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด ์ด ์ฝ”๋“œ ์˜ˆ์ œ์—์„œ ThreadLocal ์— ๋‘ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Œ ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต๊ฐœ T get() {}

  • ๊ณต๊ฐœ ๋ฌดํšจ ์ง‘ํ•ฉ(T ๊ฐ’) {}

ThreadLocal ์†Œ์Šค ์ฝ”๋“œ ์˜ setter ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค .
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}
setter ๋ฉ”์†Œ๋“œ๋Š” ๋จผ์ € ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  getMap() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ThreadLocalMap ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค . map์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ํ˜„์žฌ ์ŠคํŠธ๋ฆผ t๋ฅผ ํ‚ค๋กœ, ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  {key:value} ์Œ์„ map์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ์ง€๋„๋ฅผ ๋งŒ๋“œ์„ธ์š” . ์ด์ œ ์งˆ๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ThreadLocalMap์ด ๋ฌด์—‡์ธ๊ฐ€์š” ?
static class ThreadLocalMap {
   /**
    * The entries in this hash map extend WeakReference, using
    * its main ref field as the key (which is always a
    * ThreadLocal object).  Note that null keys (i.e. entry.get()
    * == null) mean that the key is no longer referenced, so the
    * entry can be expunged from table.  Such entries are referred to
    * as "stale entries" in the code that follows.
    */
    static class Entry extends WeakReference<ThreadLocal<?>> {
       /** The value associated with this ThreadLocal. */
       Object value;
       Entry(ThreadLocal<?> k, Object v) {
           super(k);
           value = v;
       }
    }
}
ThreadLocalMap์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ Entry ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ThreadLocal ์˜ ๋‚ด๋ถ€ ์ •์  ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค . Entry๋Š” ThreadLocal ์ธ์Šคํ„ด์Šค๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉ ํ•˜๊ณ  ์ „๋‹ฌํ•˜๋Š” ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ ์ด๊ฒƒ์ด ๋„ˆ๋ฌด ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ๋“ค๋ฆฐ๋‹ค๋ฉด, ์‹ค์ œ๋กœ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ThreadLocalMap ์˜ Entry ํด๋ž˜์Šค๋ผ๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ThreadLocal ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์œผ๋ ค๋ฉด getter ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค .
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
}
getter ๋ฉ”์†Œ๋“œ ์—์„œ๋Š” currentThread๋ฅผ Key๋กœ ์‚ฌ์šฉํ•˜์—ฌ ThreadLocalMap์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค . ๊ทธ๋Ÿฐ ๋‹ค์Œ map์€ ThreadLocal ์ธ์Šคํ„ด์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ getEntry()๋ฅผ ์ˆ˜ํ–‰ ํ•˜๊ณ  Entry ์ธ์Šคํ„ด์Šค ์™€ ์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160.  Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.  Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค - 3์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160.  Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.  Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค - 4
  1. ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ThreadLocalMap ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค .

  2. ThreadLocalMap์€ ThreadLocal ์˜ ๋‚ด๋ถ€ ์ •์  ํด๋ž˜์Šค ์ด๋ฉฐ ์ €์žฅ์„ ์œ„ํ•ด Entry ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค .

  3. ThreadLocalMap ํ‚ค๋Š” ThreadLocal์˜ ์ธ์Šคํ„ด์Šค ์ด๋ฉฐ ์—ฌ๋Ÿฌ ThreadLocal์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

  4. ThreadLocal ์ž์ฒด๋Š” ๊ฐ’์„ ์ €์žฅํ•˜์ง€ ์•Š์ง€๋งŒ ThreadLocalMap ์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์Šค๋ ˆ๋“œ์˜ ํ‚ค์ž…๋‹ˆ๋‹ค .

Entry ํด๋ž˜์Šค ์˜ "์•ฝํ•œ" ์ฐธ์กฐ๋กœ ์ธํ•œ OOM(๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์˜ค๋ฅ˜)์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ThreadLocal์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์Šต๋‹ˆ๋‹ค .

Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค

์ถœ์ฒ˜: Medium ์ด ๊ฒŒ์‹œ๋ฌผ์€ Java์˜ Scanner ํด๋ž˜์Šค์— ์ต์ˆ™ํ•ด์ง€๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. Java์˜์ปคํ”ผ ๋ธŒ๋ ˆ์ดํฌ #160.  Java ThreadLocal์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.  Java์˜ ์Šค์บ๋„ˆ ํด๋ž˜์Šค - 5 Scanner ํด๋ž˜์Šค๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์–ป๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์˜ˆ์ œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ์ข€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Scanner ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ€์น˜๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์ทจํ•˜๋Š” ์„ธ ๋‹จ๊ณ„ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์Šค์บ๋„ˆ ํด๋ž˜์Šค์—์„œ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
Scanner scan=new Scanner(System.in);
์ด์ œ ์Šค์บ๋„ˆ ๊ฐ์ฒด๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐœ์ฒด๋Š” Scanner ํด๋ž˜์Šค ์˜ Scanner ์†์„ฑ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค . ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„ ์ดํ›„์—๋Š” ์ด๋ฏธ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๊ฐ’์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์‚ฌ์šฉ์ž์—๊ฒŒ ์•ˆ๋‚ดํ•˜์ง€ ์•Š๊ณ  ์ฝ˜์†”์ด๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ทธ ๊ฐ’์„ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์‚ฌ์šฉ์„ฑ ์ธก๋ฉด์—์„œ ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์Œ ์‚ฌํ•ญ์„ ์•Œ๋ฆฌ๊ณ  ์•ˆ๋‚ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
System.out.println("Please enter your name");
String name=scan.next();
System.out.println("Your Name:"+name);
์ฒซ ๋ฒˆ์งธ ์ค„์—์„œ ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ๋ฌป์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹ค์ œ๋กœ ์Šค์บ๋„ˆ์™€ ์•„๋ฌด ๊ด€๋ จ์ด ์—†์ง€๋งŒ ์‚ฌ์šฉ์ž์—๊ฒŒ ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์ข‹์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ค„์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ์— ์ž…๋ ฅํ•˜๋Š” ๊ฐ’์„ ํ• ๋‹นํ•˜๊ณ  ๋‚˜์ค‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์ค„์—์„œ๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๊ฐ’์„ ์žฌ๋Ÿ‰์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ์— ๋ช‡ ๊ฐ€์ง€ ์„ธ๋ถ€์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
System.out.println("Please enter your last name");

String lastName=scan.next();

System.out.println("Your Name " + name + " " + "Your Last Name" + lastName);
๊ธฐ๋ณธ์ ์œผ๋กœ ์ด์ „ ๋‘ ์ค„์„ ๋ฐ˜๋ณตํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ฐ’์„ ์š”์ฒญํ•œ ํ›„ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋งˆ์ง€๋ง‰ ์ค„์—์„œ ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์™€์„œ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
์ฝ”๋ฉ˜ํŠธ
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION