# [Java] Thread



์š”์ฆ˜ OS๋Š” ๋ชจ๋‘ ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์„ ์ง€์›ํ•œ๋‹ค.


๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์ด๋ž€?

์˜ˆ๋ฅผ ๋“ค๋ฉด, ์ปดํ“จํ„ฐ๋กœ ์Œ์•…์„ ๋“ค์œผ๋ฉด์„œ ์›น์„œํ•‘๋„ ํ•˜๋Š” ๊ฒƒ

์‰ฝ๊ฒŒ ๋งํ•ด์„œ ๋‘ ๊ฐ€์ง€ ์ด์ƒ์˜ ์ž‘์—…์„ ๋™์‹œ์— ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.


์‹ค์ œ๋กœ ๋™์‹œ์— ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ๊ฐœ์ˆ˜๋Š” CPU ์ฝ”์–ด์˜ ๊ฐœ์ˆ˜์™€ ๋™์ผํ•œ๋ฐ, ์ด๋ณด๋‹ค ๋งŽ์€ ๊ฐœ์ˆ˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋‘ ํ•จ๊ป˜ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜๋Š” ์—†๋‹ค.

๊ฐ ์ฝ”์–ด๋“ค์€ ์•„์ฃผ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ํ†ตํ•ด ๋™์‹œ์— ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•  ๋ฟ์ด๋‹ค.

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


# ์Šค๋ ˆ๋“œ ๊ตฌํ˜„


์ž๋ฐ”์—์„œ ์Šค๋ ˆ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. # Runnable ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„

  2. # Thread ํด๋ž˜์Šค ์ƒ์†

๋‘˜๋‹ค run() ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.


public class MyThread implements Runnable {
    @Override
    public void run() {
        // ์ˆ˜ํ–‰ ์ฝ”๋“œ
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        // ์ˆ˜ํ–‰ ์ฝ”๋“œ
    }
}

# ์Šค๋ ˆ๋“œ ์ƒ์„ฑ


ํ•˜์ง€๋งŒ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐฉ๋ฒ•์— ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒฝ์šฐ๋Š”, ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์„œ Thread ์ƒ์„ฑ์ž์— argument๋กœ ๋„˜๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  run()์„ ํ˜ธ์ถœํ•˜๋ฉด Runnable ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๊ตฌํ˜„ํ•œ run()์ด ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ๋”ฐ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.


public static void main(String[] args) {
    Runnable r = new MyThread();
    Thread t = new Thread(r, "mythread");
}

Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฒฝ์šฐ๋Š”, ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค ์ž์ฒด๋ฅผ ์Šค๋ ˆ๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜, Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉด ์Šค๋ ˆ๋“œ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ(getName())๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, Runnable ๊ตฌํ˜„์˜ ๊ฒฝ์šฐ Thread ํด๋ž˜์Šค์˜ static ๋ฉ”์†Œ๋“œ์ธ currentThread()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์–ป์–ด์™€์•ผ๋งŒ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


public class ThreadTest implements Runnable {
    public ThreadTest() {}
    
    public ThreadTest(String name){
        Thread t = new Thread(this, name);
        t.start();
    }
    
    @Override
    public void run() {
        for(int i = 0; i <= 50; i++) {
            System.out.print(i + ":" + Thread.currentThread().getName() + " ");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

# ์Šค๋ ˆ๋“œ ์‹คํ–‰

์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์€ run() ํ˜ธ์ถœ์ด ์•„๋‹Œ start() ํ˜ธ์ถœ๋กœ ํ•ด์•ผํ•œ๋‹ค.

Why?

์šฐ๋ฆฌ๋Š” ๋ถ„๋ช… run() ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ–ˆ๋Š”๋ฐ, ์‹ค์ œ ์Šค๋ ˆ๋“œ ์ž‘์—…์„ ์‹œํ‚ค๋ ค๋ฉด start()๋กœ ์ž‘์—…ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

run()์œผ๋กœ ์ž‘์—… ์ง€์‹œ๋ฅผ ํ•˜๋ฉด ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์„ ์•ˆํ• ๊นŒ? ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. ๋‘ ๋ฉ”์†Œ๋“œ ๋ชจ๋‘ ๊ฐ™์€ ์ž‘์—…์„ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ run() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์ด๊ฑด ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.


Java์—๋Š” ์ฝœ ์Šคํƒ(call stack)์ด ์žˆ๋‹ค. ์ด ์˜์—ญ์ด ์‹ค์งˆ์ ์ธ ๋ช…๋ น์–ด๋“ค์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋กœ, ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ ์‹คํ–‰์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋งŒ์•ฝ ๋™์‹œ์— ๋‘ ๊ฐ€์ง€ ์ž‘์—…์„ ํ•œ๋‹ค๋ฉด, ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ฝœ ์Šคํƒ์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.

์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค๋Š” ๊ฑด, JVM์ด ๋‹ค์ˆ˜์˜ ์ฝœ ์Šคํƒ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์ผ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์‚ฌ์šฉ์ž๋Š” ๋™์‹œ์— ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์—ฌ์ค€๋‹ค.

์ฆ‰, run() ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ main()์˜ ์ฝœ ์Šคํƒ ํ•˜๋‚˜๋งŒ ์ด์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์Šค๋ ˆ๋“œ ํ™œ์šฉ์ด ์•„๋‹ˆ๋‹ค. (๊ทธ๋ƒฅ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด์˜ run์ด๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๊ฒŒ ๋˜๋Š” ๊ฒƒ..)

start() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, JVM์€ ์•Œ์•„์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์œ„ํ•œ ์ฝœ ์Šคํƒ์„ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ณ  context switching์„ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๋‹ต๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ํ•ด์ค€๋‹ค.

์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์ฝœ ์Šคํƒ์„ ๋งŒ๋“ค์–ด ์ž‘์—…์„ ํ•ด์•ผ ์Šค๋ ˆ๋“œ ์ผ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— start() ๋ฉ”์†Œ๋“œ๋ฅผ ์จ์•ผํ•˜๋Š” ๊ฒƒ์ด๋‹ค!

start()๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ฝœ ์Šคํƒ์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ run()์„ ํ˜ธ์ถœํ•ด์„œ ๊ทธ ์Šคํƒ ์•ˆ์— run()์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

# ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์ œ์–ด

์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๋Š” 5๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค


  • NEW : ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์•„์ง start()๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ์ƒํƒœ

  • RUNNABLE : ์‹คํ–‰ ์ค‘ ๋˜๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅ ์ƒํƒœ

  • BLOCKED : ๋™๊ธฐํ™” ๋ธ”๋Ÿญ์— ์˜ํ•ด ์ผ์‹œ์ •์ง€๋œ ์ƒํƒœ(lock์ด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ)

  • WAITING, TIME_WAITING : ์‹คํ–‰๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ์ผ์‹œ์ •์ง€ ์ƒํƒœ

  • TERMINATED : ์Šค๋ ˆ๋“œ ์ž‘์—…์ด ์ข…๋ฃŒ๋œ ์ƒํƒœ


์Šค๋ ˆ๋“œ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์šด ์ด์œ ๋Š” ๋ฐ”๋กœ ๋™๊ธฐํ™”์™€ ์Šค์ผ€์ค„๋ง ๋•Œ๋ฌธ์ด๋‹ค.

์Šค์ผ€์ค„๋ง๊ณผ ๊ด€๋ จ๋œ ๋ฉ”์†Œ๋“œ๋Š” sleep(), join(), yield(), interrupt()์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค.

start() ์ดํ›„์— join()์„ ํ•ด์ฃผ๋ฉด main ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋‘ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ์ผ๋„ ํ•ด์ค€๋‹ค.



# ๋™๊ธฐํ™”

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ๊ตฌํ˜„์„ ํ•˜๋‹ค๋ณด๋ฉด, ๋™๊ธฐํ™”๋Š” ํ•„์ˆ˜์ ์ด๋‹ค.

๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋Š”, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ๋‚ด์˜ ์ž์›์„ ๊ณต์œ ํ•˜๋ฉด์„œ ์ž‘์—…ํ•  ๋•Œ ์„œ๋กœ์˜ ์ž‘์—…์ด ๋‹ค๋ฅธ ์ž‘์—…์— ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์Šค๋ ˆ๋“œ์˜ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด์„ , ์ž„๊ณ„ ์˜์—ญ(critical section)๊ณผ ์ž ๊ธˆ(lock)์„ ํ™œ์šฉํ•œ๋‹ค.

์ž„๊ณ„์˜์—ญ์„ ์ง€์ •ํ•˜๊ณ , ์ž„๊ณ„์˜์—ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” lock์„ ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—๊ฒŒ๋งŒ ๋นŒ๋ ค์ฃผ๋Š” ๊ฐœ๋…์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ž„๊ณ„๊ตฌ์—ญ ์•ˆ์—์„œ ์ˆ˜ํ–‰ํ•  ์ฝ”๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด, lock์„ ๋ฐ˜๋‚ฉํ•ด์ค˜์•ผ ํ•œ๋‹ค.


# ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•

  • ์ž„๊ณ„ ์˜์—ญ(critical section) : ๊ณต์œ  ์ž์›์— ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก(ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ๊ฐ€๋Šฅ)

  • ๋ฎคํ…์Šค(mutex) : ๊ณต์œ  ์ž์›์— ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก(์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋„ ๊ฐ€๋Šฅ)

  • ์ด๋ฒคํŠธ(event) : ํŠน์ •ํ•œ ์‚ฌ๊ฑด ๋ฐœ์ƒ์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์•Œ๋ฆผ

  • ์„ธ๋งˆํฌ์–ด(semaphore) : ํ•œ์ •๋œ ๊ฐœ์ˆ˜์˜ ์ž์›์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ ‘๊ทผ ์ œํ•œ

  • ๋Œ€๊ธฐ ๊ฐ€๋Šฅ ํƒ€์ด๋จธ(waitable timer) : ํŠน์ • ์‹œ๊ฐ„์ด ๋˜๋ฉด ๋Œ€๊ธฐ ์ค‘์ด๋˜ ์Šค๋ ˆ๋“œ ๊นจ์›€


# synchronized ํ™œ์šฉ

synchronized๋ฅผ ํ™œ์šฉํ•ด ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐ์ฒด๊ฐ€ ๋™๊ธฐํ™”๋ฅผ ํ•˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ™์ด ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์„œ ์ด์šฉํ•˜๋ฉด, ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ง„ํ–‰๋˜๋ฏ€๋กœ ์›ํ•˜๋Š” ์ถœ๋ ฅ ๊ฐ’์„ ์–ป์ง€ ๋ชปํ•œ๋‹ค.

์ด๋•Œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋˜๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ์— synchronized ํ‚ค์›Œ๋“œ๋กœ ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.


//synchronized : ์Šค๋ ˆ๋“œ์˜ ๋™๊ธฐํ™”. ๊ณต์œ  ์ž์›์— lock
public synchronized void saveMoney(int save){    // ์ž…๊ธˆ
    int m = money;
    try{
        Thread.sleep(2000);    // ์ง€์—ฐ์‹œ๊ฐ„ 2์ดˆ
    } catch (Exception e){

    }
    money = m + save;
    System.out.println("์ž…๊ธˆ ์ฒ˜๋ฆฌ");

}

public synchronized void minusMoney(int minus){    // ์ถœ๊ธˆ
    int m = money;
    try{
        Thread.sleep(3000);    // ์ง€์—ฐ์‹œ๊ฐ„ 3์ดˆ
    } catch (Exception e){

    }
    money = m - minus;
    System.out.println("์ถœ๊ธˆ ์™„๋ฃŒ");
}

# wait()๊ณผ notify() ํ™œ์šฉ

์Šค๋ ˆ๋“œ๊ฐ€ ์„œ๋กœ ํ˜‘๋ ฅ๊ด€๊ณ„์ผ ๊ฒฝ์šฐ์—๋Š” ๋ฌด์ž‘์ • ๋Œ€๊ธฐ์‹œํ‚ค๋Š” ๊ฒƒ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‹คํ–‰๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•œ๋‹ค.

  • wait() : ์Šค๋ ˆ๋“œ๊ฐ€ lock์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด, lock ๊ถŒํ•œ์„ ๋ฐ˜๋‚ฉํ•˜๊ณ  ๋Œ€๊ธฐํ•˜๊ฒŒ ๋งŒ๋“ฌ

  • notify() : ๋Œ€๊ธฐ ์ƒํƒœ์ธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๋‹ค์‹œ lock ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ณ  ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ฌ

์ด ๋‘ ๋ฉ”์†Œ๋“œ๋Š” ๋™๊ธฐํ™” ๋œ ์˜์—ญ(์ž„๊ณ„ ์˜์—ญ)๋‚ด์—์„œ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

๋™๊ธฐํ™” ์ฒ˜๋ฆฌํ•œ ๋ฉ”์†Œ๋“œ๋“ค์ด ๋ฐ˜๋ณต๋ฌธ์—์„œ ํ™œ์šฉ๋œ๋‹ค๋ฉด, ์˜๋„ํ•œ๋Œ€๋กœ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. ์ด๋•Œ wait()๊ณผ notify()๋ฅผ try-catch ๋ฌธ์—์„œ ์ ์ ˆํžˆ ํ™œ์šฉํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.


/**
* ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ์ค‘ ํ˜‘๋ ฅ๊ด€๊ณ„ ์ฒ˜๋ฆฌ์ž‘์—… : wait() notify()
* ์Šค๋ ˆ๋“œ ๊ฐ„ ํ˜‘๋ ฅ ์ž‘์—… ๊ฐ•ํ™”
*/

public synchronized void makeBread(){
    if (breadCount >= 10){
        try {
            System.out.println("๋นต ์ƒ์‚ฐ ์ดˆ๊ณผ");
            wait();    // Thread๋ฅผ Not Runnable ์ƒํƒœ๋กœ ์ „ํ™˜
        } catch (Exception e) {

        }
    }
    breadCount++;    // ๋นต ์ƒ์‚ฐ
    System.out.println("๋นต์„ ๋งŒ๋“ฆ. ์ด " + breadCount + "๊ฐœ");
    notify();    // Thread๋ฅผ Runnable ์ƒํƒœ๋กœ ์ „ํ™˜
}

public synchronized void eatBread(){
    if (breadCount < 1){
        try {
            System.out.println("๋นต์ด ์—†์–ด ๊ธฐ๋‹ค๋ฆผ");
            wait();
        } catch (Exception e) {

        }
    }
    breadCount--;
    System.out.println("๋นต์„ ๋จน์Œ. ์ด " + breadCount + "๊ฐœ");
    notify();
}

์กฐ๊ฑด ๋งŒ์กฑ ์•ˆํ•  ์‹œ wait(), ๋งŒ์กฑ ์‹œ notify()๋ฅผ ๋ฐ›์•„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์ตœ์ข… ์ˆ˜์ • : 11/15/2021, 1:31:19 PM