์ผ๋จ ์๋์ 3๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ์์ฐจ์ ์ผ๋ก ๋ณด์.
thread-A ์ ํธ์ถ์ด ๋๋๋ฉด์ nameStore ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ๋ฐ๋๋ฐ, ์ด๋ nameStore ๋ ์์ 2๋ฒ์์ userB ์ ๊ฐ์ผ๋ก ๋์ฒด๋์๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก Thread-A ์ ์ฅ์์๋ ์ ์ฅํ ๋ฐ์ดํฐ์ ์กฐํํ ๋ฐ์ดํฐ๊ฐ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์ด์ฒ๋ผ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ ๊ฐ์ ์ธ์คํด์ค์ ํ๋ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ๋์์ฑ ๋ฌธ์ ๋ผ ํ๋ค.
์ด๋ฐ ๋์์ฑ ๋ฌธ์ ๋ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๊ฐ์ ์ธ์คํด์ค์ ํ๋์ ์ ๊ทผํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํธ๋ํฝ์ด ์ ์ ์ํฉ์์๋ ํ๋ฅ ์ ์ ๋ํ๋์ง ์๊ณ , ํธ๋ํฝ์ด ์ ์ ๋ง์์ง ์ ๋ก ์์ฃผ ๋ฐ์ํ๋ค.
์ด๋ฐ ๋์์ฑ ๋ฌธ์ ๋ ์ง์ญ ๋ณ์์์๋ ๋ฐ์ํ์ง ์๋๋ค. ์ง์ญ ๋ณ์๋ ์ฐ๋ ๋๋ง๋ค ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ํ ๋น๋๋ค.
๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ณณ์ ๊ฐ์ ์ธ์คํด์ค์ ํ๋(์ฃผ๋ก ์ฑ๊ธํค์์ ์์ฃผ ๋ฐ์), ๋๋ static ๊ฐ์ ๊ณต์ฉ ํ๋์ ์ ๊ทผํ ๋ ๋ฐ์ํ๋ค. ๋์์ฑ ๋ฌธ์ ๋ ๊ฐ์ ์ฝ๊ธฐ๋ง ํ๋ฉด ๋ฐ์ํ์ง ์๋๋ค. ์ด๋์ ๊ฐ ๊ฐ์ ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ค.
์ฌ๋ฌ๊ฐ์ ์ค๋ ๋๊ฐ ์กด์ฌํ ๋, ํด๋น ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๋ ํน๋ณํ ์ ์ฅ์๋ฅผ ์๋ฏธํ๋ค. ๋ ํ์ด์ ์ด์ผ๊ธฐ ํด๋ณด์. ๋ง์ฝ ์๋ก ๋ค๋ฅธ ๋ ์ค๋ ๋๊ฐ ํ๋์ ๋ณ์์ ์ ๊ทผํ๋ค๊ณ ํ ๋, ์ด ๋ณ์๋ ๊ณต์ ์์์ผ๋ก ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ค๋ถํ๋ค. ThreadLocal ํด๋์ค๋ ์ค์ง ํ ์ค๋ ๋์ ์ํด ์ฝ๊ณ /์ฐ์ฌ์ง ์ ์๋ ๋ณ์๋ฅผ ์์ฑํ๋ค.
๊ฐ๋ น Thread A ๊ฐ ThreadLocal ๋ณ์( tLocal ) ์ ์ ๊ทผํ์ฌ a ๋ผ๋ ๋ฌธ์๋ฅผ ์ ์ฅํ๋ค๊ณ ํ์. ๋์์ Thread B ์์ ๋ง์ฐฌ๊ฐ์ง๋ก tLocal ๋ณ์์ ์ ๊ทผํ์ฌ, b ๋ผ๋ ๋ฌธ์๊ฐ์ ์ ์ฅํ๋ค๊ณ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น? a ๋ผ๋ ๋ฌธ์๋ฅผ b ๊ฐ ๋ฎ์ด ๋ฒ๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ, ์๋ ์ฒ๋ผ ๊ฐ ์ค๋ ๋๋ณ ์ ์ฉ ์ ์ฅ์์ ๊ฐ๊ฐ์ ๊ฐ์ด ์ ์ฅ๋๋ค. ์ฆ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ๊ณต์ ์์์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ฒ ๋๋ ๊ฒ์ด๋ค.
ThreadLocal<String> threadLocal = new ThreadLocal<>();
์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ฌ ํ์ ์ง์ ํ ์ ์๋ค.
threadLocal.set("a") // thread local ๊ฐ ์ ์ฅ
threadLocal.get() // ์ ์ฅ๋ ๊ฐ ๋ถ๋ฌ์ค๊ธฐ
์ ์ธ๋ threadLocal ๋ณ์์ set(), get() ๋ฉ์๋๋ฅผ ์ด์ฉํด Thread Local ๊ฐ์ ์ฐ๊ณ ์ฝ์ ์ ์๋ค.
์๋ฌด ๊ฐ๋ ์ ์ฅ๋์ง ์์ Thread Local์ ๊ฐ์ ์ฝ์ผ๋ฉด(get()) null ์ ๋ฐํํ๋ค.
@Slf4j
public class ThreadLocalServiceTest {
private ThreadLocal<String> threadLocal = new ThreadLocal<>();
@Test
void field() {
Runnable userC = () -> {
log.info("start");
String value = threadLocal.get();
log.info("value : {}", value);
log.info("set threadLocal value : A");
threadLocal.set("A");
value = threadLocal.get();
log.info("threadLocal : {}", value);
};
Thread threadC = new Thread(userC);
threadC.setName("thread-C");
threadC.start();
}
}
Thread Local์ ๋ชจ๋ ์ฌ์ฉํ๊ณ ๋๋ฉด ๋ฐ๋์ ThreadLocal.remove() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ, Thread Local์ ์ ์ฅ๋ ๊ฐ์ ์ ๊ฑฐํด์ผ ํ๋ค.
Thread Local์ ๊ฐ์ ์ ๊ฑฐํ์ง ์์ผ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง ์๋์ ์ด๋ฏธ์ง๋ฅผ ํตํด ํ์ธํด๋ณด์.
-
์ฌ์ฉ์ A ๊ฐ ์ ์ฅ HTTP ์์ฒญ์ ๋ณด๋ธ๋ค.
-
WAS ๋ ์ค๋ ๋ํ์์ ์ค๋ ๋๋ฅผ ํ๋ ์กฐํํ๋ค.
-
ํด๋น ์ค๋ ๋๋ thread-A ๊ฐ ํ ๋น ๋์๊ณ , ์ฌ์ฉ์ A ์ ๋ฐ์ดํฐ๋ฅผ Thread Local์ ์ ์ฅํ๋ค.
-
Thread Local thread-A ์ ์ฉ ๋ณด๊ด์์ ์ฌ์ฉ์A ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ๋ค.
-
์ฌ์ฉ์ A ์ HTTP ์์ฒญ์ด ์ข ๋ฃ๋๋ฉด, thread-A ๋ ๋ค์ ์ค๋ ๋ ํ์ ๋ฐํ๋๋ค.
-
thread-A ๋ ์ค๋ ๋ ํ์ ํตํด์ ์ฌ์ฌ์ฉ ๋ ์ ์๋ค.
-
์ฌ์ฉ์ B ์์ HTTP ์กฐํ ์์ฒญ์ ๋ณด๋ธ๋ค.
-
์ค๋ ๋ ํ์์ ํํ thread-A ๊ฐ ํ ๋น๋์๋ค.
-
์กฐํ ์์ฒญ์ด๊ธฐ ๋๋ฌธ์ ์ค๋ ๋ ํ์ thread-A ์ ์ฉ ๊ณต๊ฐ์์, ์ด์ ์ ์ ์ฅํด๋ ๊ฐ์ด ์กฐํ๋๋ค.
-
์ฆ ์ฌ์ฉ์ B ๊ฐ ์์ํ ์กฐํ ๊ฒฐ๊ณผ๊ฐ ์๋, ์ฌ์ฉ์ A ๊ฐ ์ ์ฅํด๋ ๊ฐ์ด ์กฐํ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.