์ž๋ฐ” ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ๊ตฌํ˜„ํ•˜๊ธฐ

์ž๋ฐ”์—์„œ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ๋กœ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๊ฐ„๋žตํ•˜๊ฒŒ ํฌ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค.

 

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

์ฒซ ๋ฒˆ์งธ๋Š” Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ Thread ์ƒ์„ฑ์ž๋กœ ํ•ด๋‹น ๊ตฌํ˜„์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด๊ณ ,

๋‘ ๋ฒˆ์งธ๋Š” ์ง์ ‘ Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์šฐ์„  ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ  ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        Runnable task = new Task();
        Thread thread = new Thread(task);
        thread.start();
    }
    static class Task implements Runnable {

        int num = 0;

        @Override
        public void run() {
        	for(int i = 0; i < 10; i++) {
	            System.out.println(num++);
            }
        }
    }

 

์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ์ด ๋ฉ๋‹ˆ๋‹ค.

	0
	1
	2
	3
	4
	5
	6
	7
	8
	9

 

์ด๋ฒˆ์—๋Š” Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜์—ฌ ๋™์ผํ•œ ์ž‘์—…(task)์„ ํ•˜๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        ThreadTask task = new ThreadTask();
        task.run();        
    }
    static class ThreadTask extends Thread {

        int num = 0;

        @Override
        public void run() {
        	for(int i = 0; i < 10; i++) {
	            System.out.println(num++);
    	    }
        }
    }

 

์‹คํ–‰ํ•˜๋ฉด Runnable๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ์™€ ๋™์ผํ•˜๊ฒŒ ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ์ด ๋ฉ๋‹ˆ๋‹ค.

	0
	1
	2
	3
	4
	5
	6
	7
	8
	9

 

์ฐธ๊ณ ๋กœ ์‹ค์ œ Thread ํด๋ž˜์Šค๋ฅผ ์—ด์–ด๋ณด๋ฉด Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ implementํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

public class Thread implements Runnable {
    /* Make sure registerNatives is the first thing <clinit> does. */
    private static native void registerNatives();
    static {
        registerNatives();
    }

    private volatile String name;
    private int            priority;
    private Thread         threadQ;
    private long           eetop;
.
.
.

 

๊ทธ๋Ÿผ ์ด๋ฒˆ์—๋Š” ์“ฐ๋ ˆ๋“œ ๋‘ ๊ฐœ๋ฅผ ๋™์‹œ์— ๋Œ๋ ค๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

    public static void main(String[] args) {
        Runnable task = new Task();

        Thread thread1 = new Thread(task);
        thread1.start();
        System.out.println("thread 1 executed.");

        Thread thread2 = new Thread(task);
        thread2.start();
        System.out.println("thread 2 executed.");

        System.out.println("์“ฐ๋ ˆ๋“œ ์ฝœ ์ข…๋ฃŒ");
    }

    static class Task implements Runnable {

        int num = 0;

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + ", num=" + num++);
            }
        }
    }

 

์ค‘๊ฐ„์ค‘๊ฐ„์— ์–ด๋–ป๊ฒŒ ์‹คํ–‰์ด ๋˜๋Š”์ง€ ํ™•์ธ์„ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ System.out.println์œผ๋กœ ๋กœ๊น…์„ ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

thread 1 executed.
Thread-0, num=0
Thread-0, num=1
Thread-0, num=2
Thread-0, num=3
Thread-0, num=4
Thread-0, num=5
thread 2 executed.
์“ฐ๋ ˆ๋“œ ์ฝœ ์ข…๋ฃŒ
Thread-0, num=6
Thread-1, num=7
Thread-1, num=9
Thread-0, num=8
Thread-1, num=10
Thread-0, num=11
Thread-1, num=12
Thread-1, num=13
Thread-1, num=14
Thread-1, num=16
Thread-1, num=17
Thread-1, num=18
Thread-1, num=19
Thread-0, num=15

BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date

 

์œ„ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋จผ์ € ์‹œ์ž‘๋˜์ง€๋งŒ "task1 executed"๊ฐ€ ๋จผ์ € ์ถœ๋ ฅ์ด ๋˜์—ˆ๊ณ  ๊ทธ ๋’ค์— ์ฒซ ๋ฒˆ์งธ ์“ฐ๋ ˆ๋“œ์ธ Thread-0์ด ์ถœ๋ ฅ์„ ์‹œ์ž‘ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ค‘๊ฐ„์— "task2 executed"๊ฐ€ ์ถœ๋ ฅ๋œ ๊ฑธ ๋ณด๋‹ˆ ๋‘ ๋ฒˆ์งธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰์ด ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์ฃ . ๋‘ ๋ฒˆ์งธ ์“ฐ๋ ˆ๋“œ๋Š” Thread-1 ์ด๋ฉฐ ์ฒซ ๋ฒˆ์งธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ผ์„ ๋งˆ์น˜๊ธฐ ์ „์— ์‹œ์ž‘๋˜์–ด "Thread-1, num=0"์„ ์ถœ๋ ฅํ•œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค(main ํ”„๋กœ์„ธ์Šค) ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์—…์„ ๋™์‹œ์— ๋‚˜๋ˆ„์–ด ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์ด ์“ฐ๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค.

์“ฐ๋ ˆ๋“œ๋กœ ์ž‘์—…์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง•๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ด ์†Œ์š” ์‹œ๊ฐ„์ด ์ค„์–ด๋“ ๋‹ค. (๋ฉ”์ธ์“ฐ๋ ˆ๋“œ 1๊ฐœ๋กœ ์ž‘์—…ํ–ˆ์„ ๋•Œ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ)
  • ๋จผ์ € ์‹œ์ž‘ํ•œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ•ญ์ƒ ๋จผ์ € ์ผ์„ ๋๋‚ด์ง€๋Š” ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ, ์ž‘์—…์˜ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•  ๋•Œ์—๋Š” ์“ฐ๋ ˆ๋“œ๋กœ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

 

์ž, ์ด์ œ ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ๋กœ 10์‹œ๊ฐ„ ๊ฑธ๋ฆด ์ผ์„ 100๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋Œ๋ ค์„œ 10๋ถ„๋งŒ์— ๋๋‚ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”?

์“ฐ๋ ˆ๋“œ๋ฅผ 100๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๋ฐ ์•„๋ž˜์ฒ˜๋Ÿผ ๋ฌด์‹ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ• ๊นŒ์š”?

        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);
        Thread thread3 = new Thread(task);
        Thread thread4 = new Thread(task);
        Thread thread5 = new Thread(task);
        .
        .
        .

 

์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์•ผ๋˜๋ฉด ์“ฐ๋ ˆ๋“œ ๋งŒ๋“ค๋‹ค๊ฐ€ ํ‡ด๊ทผํ•ด์•ผ๋ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์—์„œ๋Š” java.util.concurrentํŒจํ‚ค์ง€์— ๋™์‹œ์ž‘์—…์„ ์œ„ํ•ด ์œ ์šฉํ•œ ํด๋ž˜์Šค๋“ค์„ ๋ชจ์•„๋†จ๋Š”๋ฐ ๊ทธ์ค‘์— ThreadPoolExecutor๋ผ๋Š” ๋…€์„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋…€์„์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‘ ์„ธ ์ค„์ด๋ฉด 100๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์ฃ .

ThreadPoolExecutor์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๋ ค๋ฉด ํฌ์ŠคํŠธ๊ฐ€ ๊ธธ์–ด์ง€๋‹ˆ ThreadPoolExecutor๋ฅผ ์ด์šฉํ•œ ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ๊ตฌํ˜„์„œ ๊ณ„์† ์ด์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.