์ด ๋‹จ์›์—์„œ๋Š” java.lang.ThreadLocal<> ํด๋ž˜์Šค ์ž‘์—…๊ณผ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์— ๋Œ€ํ•ด ์ผ๋ฐ˜์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค .

ThreadLocal ํด๋ž˜์Šค๋Š” ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค์˜ ํŠน์ง•์€ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ๊ฐ’์˜ ๋ณ„๋„์˜ ๋…๋ฆฝ์ ์ธ ๋ณต์‚ฌ๋ณธ์„ ์œ ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํด๋ž˜์Šค์˜ ์ž‘๋™์„ ๋” ๊นŠ์ด ํŒŒ๊ณ ๋“ค๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ’์— ๋งคํ•‘ํ•˜๋Š” ๋งต์„ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ ์ ์ ˆํ•œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

ThreadLocal ํด๋ž˜์Šค ์ƒ์„ฑ์ž

๊ฑด์„ค์ž ํ–‰๋™
์Šค๋ ˆ๋“œ๋กœ์ปฌ() Java์—์„œ ๋นˆ ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ–‰๋™ ์–‘์‹

๋ฐฉ๋ฒ• ํ–‰๋™
์–ป๋‹ค() ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ์ง€์—ญ ๋ณ€์ˆ˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์„ธํŠธ() ํ˜„์žฌ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ง€์—ญ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
์ œ๊ฑฐํ•˜๋‹ค() ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ์ง€์—ญ ๋ณ€์ˆ˜ ๊ฐ’์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
ThreadLocal.withInitial() ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ์ถ”๊ฐ€์ ์ธ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ

get() ๋ฐ ์„ค์ •()

๋‘ ๊ฐœ์˜ ์นด์šดํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ผ๋ฐ˜ ๋ณ€์ˆ˜๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ThreadLocal ๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค . ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๊ทธ๋“ค์ด ์–ด๋–ป๊ฒŒ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋จผ์ € Runnable์„ ์ƒ์† ํ•˜๊ณ  ๋ฐ์ดํ„ฐ์™€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ run() ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” ThreadDemo ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค . ๋˜ํ•œ ํ™”๋ฉด์— ์นด์šดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.


class ThreadDemo implements Runnable {

    int counter;
    ThreadLocal<Integer> threadLocalCounter = new ThreadLocal<>();

    public void run() {
        counter++;

        if(threadLocalCounter.get() != null) {
            threadLocalCounter.set(threadLocalCounter.get() + 1);
        } else {
            threadLocalCounter.set(0);
        }
        printCounters();
    }

    public void printCounters(){
        System.out.println("Counter: " + counter);
        System.out.println("threadLocalCounter: " + threadLocalCounter.get());
    }
}

์ˆ˜์—…์ด ์ง„ํ–‰๋  ๋•Œ๋งˆ๋‹ค ์šฐ๋ฆฌ๋Š”์นด์šดํ„ฐ๋ณ€์ˆ˜๋Š” get() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ThreadLocal ๋ณ€์ˆ˜ ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค . ์ƒˆ ์Šค๋ ˆ๋“œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด 0์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด 1์”ฉ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ์˜ ์ฃผ์š” ๋ฐฉ๋ฒ•์„ ์ž‘์„ฑํ•ด ๋ด…์‹œ๋‹ค .


public static void main(String[] args) {
    ThreadDemo threadDemo = new ThreadDemo();

    Thread t1 = new Thread(threadDemo);
    Thread t2 = new Thread(threadDemo);
    Thread t3 = new Thread(threadDemo);

    t1.start();
    t2.start();
    t3.start();

}

ํด๋ž˜์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ThreadLocal ๋ณ€์ˆ˜๋Š” ์•ก์„ธ์Šคํ•˜๋Š” ์Šค๋ ˆ๋“œ์— ๊ด€๊ณ„์—†์ด ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์ง€๋งŒ ์Šค๋ ˆ๋“œ ์ˆ˜๋Š” ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์นด์šดํ„ฐ: 1
์นด์šดํ„ฐ: 2
์นด์šดํ„ฐ: 3
threadLocalCounter: 0
threadLocalCounter: 0
threadLocalCounter: 0

ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ ์ฝ”๋“œ 0์œผ๋กœ ์ข…๋ฃŒ๋จ

์ œ๊ฑฐํ•˜๋‹ค()

remove ๋ฉ”์„œ๋“œ์˜ ์ž‘๋™ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ThreadDemo ํด๋ž˜์Šค ์˜ ์ฝ”๋“œ๋ฅผ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค .


if(threadLocalCounter.get() != null) {
      threadLocalCounter.set(threadLocalCounter.get() + 1);
  } else {
      if (counter % 2 == 0) {
          threadLocalCounter.remove();
      } else {
          threadLocalCounter.set(0);
      }
  }

์ด ์ฝ”๋“œ์—์„œ ์Šค๋ ˆ๋“œ ์นด์šดํ„ฐ๊ฐ€ ์ง์ˆ˜์ด๋ฉด ThreadLocal ๋ณ€์ˆ˜ ์—์„œ remove() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค . ๊ฒฐ๊ณผ:

์นด์šดํ„ฐ: 3
threadLocalCounter: 0
์นด์šดํ„ฐ: 2
threadLocalCounter: null
์นด์šดํ„ฐ: 1
threadLocalCounter: 0

ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ ์ฝ”๋“œ 0์œผ๋กœ ์ข…๋ฃŒ๋จ

์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” ๋‘ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ์˜ ThreadLocal ๋ณ€์ˆ˜๊ฐ€ null ์ž„์„ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

ThreadLocal.withInitial()

์ด ๋ฉ”์„œ๋“œ๋Š” ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ThreadDemo ํด๋ž˜์Šค ๊ตฌํ˜„ :


class ThreadDemo implements Runnable {

    int counter;
    ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 1);

    public void run() {
        counter++;
        printCounters();
    }

    public void printCounters(){
        System.out.println("Counter: " + counter);
        System.out.println("threadLocalCounter: " + threadLocalCounter.get());
    }
}

๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์นด์šดํ„ฐ: 1
์นด์šดํ„ฐ: 2
์นด์šดํ„ฐ: 3
threadLocalCounter: 1
threadLocalCounter: 1
threadLocalCounter: 1

ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ ์ฝ”๋“œ 0์œผ๋กœ ์ข…๋ฃŒ๋จ

์™œ ๊ทธ๋Ÿฐ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

ThreadLocal์€ java.lang.Thread ์‹คํ–‰ ์Šค๋ ˆ๋“œ์™€ ๊ด€๋ จํ•˜์—ฌ ๋กœ์ปฌ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ถ”์ƒํ™”๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ThreadLocal ๋ณ€์ˆ˜๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ get() ๋ฐ set() ๋ฉ”์„œ๋“œ ๋ฅผ ํ†ตํ•ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋ณ„์ ์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ ์ž์ฒด ๋ณ€์ˆ˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ–๋Š”๋‹ค๋Š” ์ ์—์„œ ์ผ๋ฐ˜ ๋ณ€์ˆ˜์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

๊ฐ ์Šค๋ ˆ๋“œ, ์ฆ‰ Thread ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์—๋Š” ์—ฐ๊ฒฐ๋œ ThreadLocal ๋ณ€์ˆ˜ ์˜ ๋งต์ด ์žˆ์Šต๋‹ˆ๋‹ค . ๋งต์˜ ํ‚ค๋Š” ThreadLocal ๊ฐœ์ฒด ์— ๋Œ€ํ•œ ์ฐธ์กฐ ์ด๊ณ  ๊ฐ’์€ "ํš๋“ํ•œ" ThreadLocal ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ์ž…๋‹ˆ๋‹ค.

Random ํด๋ž˜์Šค๊ฐ€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•˜์ง€ ์•Š์€ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

Random ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚œ์ˆ˜๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ์ œ๋Œ€๋กœ ์ž‘๋™ํ• ๊นŒ์š”? ์‚ฌ์‹ค, ์•„๋‹ˆ์˜ค. Random์€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ํด๋ž˜์Šค์— ์•ก์„ธ์Šคํ•˜๋ฉด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด JDK 7์—์„œ๋Š” ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” java.util.concurrent.ThreadLocalRandom ํด๋ž˜์Šค๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ThreadLocal ๋ฐ Random ์˜ ๋‘ ํด๋ž˜์Šค๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค .

ํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜์‹ ํ•œ ๋‚œ์ˆ˜๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์™€ ๋…๋ฆฝ์ ์ด์ง€๋งŒ java.util.Random์€ ์ „์—ญ์ ์œผ๋กœ ๋‚œ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Random ๊ณผ ๋‹ฌ๋ฆฌ ThreadLocalRandom์€ ๋ช…์‹œ์  ์‹œ๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  Random ์—์„œ ์ƒ์†๋œ setSeed() ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋ฏ€๋กœ ํ˜ธ์ถœ ์‹œ ํ•ญ์ƒ UnsupportedOperationException์ด ๋ฐœ์ƒ ํ•ฉ๋‹ˆ๋‹ค .

ThreadLocalRandom ํด๋ž˜์Šค ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค .

๋ฐฉ๋ฒ• ํ–‰๋™
ThreadLocalRandom ์ „๋ฅ˜() ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ThreadLocalRandom์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์ •์ˆ˜ ๋‹ค์Œ(์ •์ˆ˜ ๋น„ํŠธ) ๋‹ค์Œ ์˜์‚ฌ ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
double nextDouble(๋”๋ธ” ์ตœ์†Œ, ๋”๋ธ” ๋ฐ”์šด๋“œ) ์ตœ์†Œ (ํฌํ•จ)์™€ ๋ฐ”์šด๋“œ (์ œ์™ธ) ์‚ฌ์ด์˜ ๊ท ๋“ฑ ๋ถ„ํฌ์—์„œ ์˜์‚ฌ ๋‚œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค .
int nextInt(์ ์–ด๋„ ์ •์ˆ˜, ๊ฒฝ๊ณ„ ์ •์ˆ˜) ์ตœ์†Œ(ํฌํ•จ)์™€ ๋ฐ”์šด๋“œ(์ œ์™ธ) ์‚ฌ์ด์˜ ๊ท ๋“ฑ ๋ถ„ํฌ์—์„œ ์˜์‚ฌ ๋‚œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ธด nextLong(๊ธด n) 0(ํฌํ•จ)๊ณผ ์ง€์ •๋œ ๊ฐ’(์ œ์™ธ) ์‚ฌ์ด์˜ ๊ท ์ผ ๋ถ„ํฌ์—์„œ ์˜์‚ฌ ๋‚œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ธด nextLong(๊ธด ์ตœ์†Œ, ๊ธด ๊ฒฝ๊ณ„) ์ตœ์†Œ(ํฌํ•จ)์™€ ๋ฐ”์šด๋“œ(์ œ์™ธ) ์‚ฌ์ด์˜ ๊ท ๋“ฑ ๋ถ„ํฌ์—์„œ ์˜์‚ฌ ๋‚œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๋ฌดํšจ setSeed(๊ธด ์‹œ๋“œ) UnsupportedOperationException ์„ ๋˜์ง‘๋‹ˆ๋‹ค . ์ด ์ƒ์„ฑ๊ธฐ๋Š” ์‹œ๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ThreadLocalRandom.current()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚œ์ˆ˜ ์–ป๊ธฐ

ThreadLocalRandom์€ ThreadLocal ๊ณผ Random ํด๋ž˜์Šค ์˜ ์กฐํ•ฉ์ž…๋‹ˆ๋‹ค. Random ํด๋ž˜์Šค ์˜ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๋™์‹œ ์•ก์„ธ์Šค๋ฅผ ๋‹จ์ˆœํžˆ ํ”ผํ•จ์œผ๋กœ์จ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์–ป์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ํฌํ•จ๋œ ์˜ˆ์ œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ThreadLocalRandom ํด๋ž˜์Šค๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


import java.util.concurrent.ThreadLocalRandom;

class RandomNumbers extends Thread {

    public void run() {
        try {
            int bound = 100;
            int result = ThreadLocalRandom.current().nextInt(bound);
            System.out.println("Thread " + Thread.currentThread().getId() + " generated " + result);
        }
        catch (Exception e) {
            System.out.println("Exception");
        }
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();

				for (int i = 0; i < 10; i++) {
            RandomNumbers randomNumbers = new RandomNumbers();
            randomNumbers.start();
        }

        long endTime = System.currentTimeMillis();

        System.out.println("Time taken: " + (endTime - startTime));
    }
}

์šฐ๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฒฐ๊ณผ:

์†Œ์š” ์‹œ๊ฐ„: 1
์Šค๋ ˆ๋“œ 17 ์ƒ์„ฑ 13
์Šค๋ ˆ๋“œ 18 ์ƒ์„ฑ 41
์Šค๋ ˆ๋“œ 16 ์ƒ์„ฑ 99
์Šค๋ ˆ๋“œ 19 ์ƒ์„ฑ 25
์Šค๋ ˆ๋“œ 23 ์ƒ์„ฑ 33
์Šค๋ ˆ๋“œ 24 ์ƒ์„ฑ 21
์Šค๋ ˆ๋“œ 15 ์ƒ์„ฑ 15
์Šค๋ ˆ๋“œ 21 ์ƒ์„ฑ 28
์Šค๋ ˆ๋“œ 22 ์ƒ์„ฑ 97
์Šค๋ ˆ๋“œ 20 ์ƒ์„ฑ 33

์ด์ œ RandomNumbers ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  Random์„ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค .


int result = new Random().nextInt(bound);
์†Œ์š” ์‹œ๊ฐ„: 5
์Šค๋ ˆ๋“œ 20 ์ƒ์„ฑ 48
์Šค๋ ˆ๋“œ 19 ์ƒ์„ฑ 57
์Šค๋ ˆ๋“œ 18 ์ƒ์„ฑ 90
์Šค๋ ˆ๋“œ 22 ์ƒ์„ฑ 43
์Šค๋ ˆ๋“œ 24 ์ƒ์„ฑ 7
์Šค๋ ˆ๋“œ 23 ์ƒ์„ฑ 63
์Šค๋ ˆ๋“œ 15 ์ƒ์„ฑ 2
์Šค๋ ˆ๋“œ 16 ์ƒ์„ฑ 40
์Šค๋ ˆ๋“œ 17 ์ƒ์„ฑ 29
์Šค๋ ˆ๋“œ 21 ์ƒ์„ฑ 12

ํ•„๊ธฐ ํ•ด! ํ…Œ์ŠคํŠธ์—์„œ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์„ ๋•Œ๋„ ์žˆ๊ณ  ๋‹ค๋ฅผ ๋•Œ๋„ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ(์˜ˆ: 100)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฌด์ž‘์œ„ โ€” 19-25ms
ThreadLocalRandom โ€” 17-19ms

๋”ฐ๋ผ์„œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋งŽ์„์ˆ˜๋ก ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ Random ํด๋ž˜์Šค ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์ปค์ง‘๋‹ˆ๋‹ค .

Random ํด๋ž˜์Šค ์™€ ThreadLocalRandom ํด๋ž˜์Šค ๊ฐ„์˜ ์ฐจ์ด์ ์„ ์š”์•ฝํ•˜๊ณ  ๋ฐ˜๋ณตํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์‹ญ์‹œ์˜ค .

๋ฌด์ž‘์œ„์˜ ์Šค๋ ˆ๋“œ๋กœ์ปฌ๋žœ๋ค
๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์ผํ•œ Random ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๊ณ  ์„ฑ๋Šฅ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ๋‚œ์ˆ˜๊ฐ€ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์— ๋กœ์ปฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ถฉ๋Œ์ด๋‚˜ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
์„ ํ˜• ํ•ฉ๋™ ๊ณต์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐ๊ฐ’์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์‹œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.
๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ ์œ ํ•œ Random ๊ฐœ์ฒด ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค . ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์Šค๋ ˆ๋“œ ํ’€์—์„œ ๋ณ‘๋ ฌ๋กœ ๋‚œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๋ถ€๋ชจ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž์‹ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.