ThreadLocal์ด๋ž€?

๊ทธ๋ƒฅ ์ค€ํ˜„ยท2024๋…„ 8์›” 19์ผ

Computer Science

๋ชฉ๋ก ๋ณด๊ธฐ
15/16
post-thumbnail

๐Ÿ’ก ์ด ๊ธ€์€ ํšŒ์‚ฌ ์ธํ„ด ๊ธฐ๊ฐ„์— ์Šคํ„ฐ๋””ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค!

Thread Safety๋ž€?
์œ„ ๊ธ€์— ์ด์–ด์„œ ์ž‘์„ฑ๋œ ๊ฒŒ์‹œ๊ธ€์ž…๋‹ˆ๋‹ค.

์œ„ ๊ธ€์—์„œ ์•Œ์•„๋ณธ Thread Safe๋ฅผ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ํ•ด๊ฒฐ๋ฐฉ์•ˆ์ด ์žˆ๋‹ค.
์ด ๊ธ€์—์„œ๋Š” ThreadLocal์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.

1. ThreadLocal

1.1 ๊ฐœ๋…

ThreadLocal์€ ์Šค๋ ˆ๋“œ ๋ณ„๋กœ ์ƒ์„ฑ๋˜๋Š” ๋ณ€์ˆ˜์ด๋‹ค.
์„ ์–ธ๋œ ํ˜•ํƒœ๋งŒ ๋ณด๋ฉด ๋‹ค๋ฅธ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ ๋ณ„๋กœ ํ• ๋‹น๋œ๋‹ค.

ThreadLocal์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋กœ ๊ณต์œ ํ•  ํ•„์š”๊ฐ€ ์ „ํ˜€ ์—†๋Š” ์ •๋ณด๋ฅผ ๊ฐ ์Šค๋ ˆ๋“œ ๋ณ„๋กœ ์ €์žฅํ•ด์„œ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

1.2 ๋ฉ”์„œ๋“œ

  • withInitial
  • get
  • set
  • remove

ThreadLocal์€ ํ•ด๋‹น ์ž์›์— ์ ‘๊ทผํ•˜์—ฌ CRUD ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

1.3 ์‚ฌ์šฉ ์˜ˆ์ œ

1.3.1 ThreadLocal ๋ฏธ์‚ฌ์šฉ

๋น„๊ตํ•ด์„œ ๋ณด๊ธฐ ์œ„ํ•ด ์šฐ์„  ThreadLocal์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์˜ˆ์ œ๋ถ€ํ„ฐ ๋ณด์ž.

public class SharedVariableExample {
    private static int sharedValue = 0;

    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 5; i++) {
                sharedValue++;
                System.out.println(Thread.currentThread().getName() + ": " + sharedValue);
            }
        };

        Thread thread1 = new Thread(task, "Thread-1");
        Thread thread2 = new Thread(task, "Thread-2");

        thread1.start();
        thread2.start();
    }
}
Thread-2: 2
Thread-2: 3
Thread-2: 4
Thread-2: 5
Thread-1: 1
Thread-1: 7
Thread-1: 8
Thread-1: 9
Thread-1: 10
Thread-2: 6

์˜ˆ์ œ ์ฝ”๋“œ์™€ ์ถœ๋ ฅ์€ ์œ„์™€ ๊ฐ™๋‹ค.
๋‘ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๊ฐ๊ฐ sharedValue์— 5๋ฒˆ์”ฉ ํ›„์œ„ ์ฆ๊ฐ์„ ํ•˜๋Š” ์—ฐ์‚ฐ์„ ์‹œ์ผฐ๋‹ค.

sharedValue๋Š” ์ด 10๋ฒˆ์˜ ํ›„์œ„ ์ฆ๊ฐ์„ ์ˆ˜ํ–‰ํ–ˆ๊ณ , ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž‘์—…ํ•˜๋Š” ์ˆœ์„œ ๋˜ํ•œ ๋ณด์žฅ๋˜์ง€ ์•Š์•˜๋‹ค.

ํ”„๋กœ๊ทธ๋žจ ํŠน์ง•์— ๋”ฐ๋ผ์„œ๋Š” ์ด๋Ÿฐ ๊ตฌ์กฐ๊ฐ€ ๋งˆ๋œฉ์ž–์„ ์ˆ˜ ์žˆ๋‹ค.

1.3.2 ThreadLocal ์‚ฌ์šฉ

๊ฐ™์€ ์ž‘์—…์„ ThreadLocal์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

public class ThreadLocalExample {
    private static final ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);

    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 5; i++) {
                int value = threadLocal.get();
                threadLocal.set(value + 1);
                System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get());
            }
            threadLocal.remove();
        };

        Thread thread1 = new Thread(task, "Thread-1");
        Thread thread2 = new Thread(task, "Thread-2");

        thread1.start();
        thread2.start();
    }
}
Thread-2: 1
Thread-1: 1
Thread-2: 2
Thread-1: 2
Thread-2: 3
Thread-1: 3
Thread-2: 4
Thread-1: 4
Thread-1: 5
Thread-2: 5

ThreadLocal ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•ด์„œ ๋™์ผํ•˜๊ฒŒ 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ด 5๋ฒˆ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋‘ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๊ฐ๊ฐ ์‹œ์ผฐ๋‹ค.
ThreadLocal ๋ณ€์ˆ˜๋Š” ์Šค๋ ˆ๋“œ ๋ณ„๋กœ ๊ฐ๊ฐ ์กด์žฌํ•˜๊ฒŒ ๋ผ์„œ ์ž‘์—… ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ 5๋ผ๋Š” ๊ฐ’์„ ๊ฐ๊ฐ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ThreadLocal ๋ณ€์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋ ˆ๋“œ ๋ณ„๋กœ ์™„์ „ํžˆ ๋…๋ฆฝ๋œ ์ •๋ณด์— ๋Œ€ํ•ด์„œ ThreadLocal ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ์œ ์ €์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.
๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•œ ๋ช…์˜ ์œ ์ €์— ๋Œ€ํ•ด ์ž‘์—…ํ•  ๋•Œ, ๋‚ด๊ฐ€ ๋‹ด๋‹นํ•˜์ง€ ์•Š์€ ๋‹ค๋ฅธ ์œ ์ €์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์•Œ ํ•„์š”๋„ ์—†๊ณ  ์•Œ์•„์„œ๋„ ์•ˆ ๋œ๋‹ค.

profile
์ž˜ํ•ด์•ผ ์žฌ๋ฐŒ์–ด

0๊ฐœ์˜ ๋Œ“๊ธ€