1. Executors์˜ ์—ญํ• 

2. ์ฃผ์š” Interface

3. Single Thread

4. ์›ํ•˜๋Š” Thread Pool ๊ฐœ์ˆ˜๋กœ ์ œํ•œํ•˜๊ธฐ

5. ScheduleExecutorService

1. Executors์˜ ์—ญํ• 

Thread ๋งŒ๋“ค๊ธฐ : Application์ด ์‚ฌ์šฉํ•  Thread Pool์„ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•จ.

Thread ๊ด€๋ฆฌ : Thread์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌ ํ•จ.

์ž‘์—… ์ฒ˜๋ฆฌ ๋ฐ ์‹คํ–‰ : Thread๋กœ ์‹คํ–‰ํ•  ์ž‘์—…์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ์ œ๊ณตํ•จ.

2. ์ฃผ์š” Interface

3. Single Thread

//์‹ฑ๊ธ€์Šค๋ ˆ๋“œ ์‚ฌ์šฉ
ExecutorService executorService = Executors.newSingleThreadExecutor();
//์‚ฌ์šฉ๋ฐฉ๋ฒ• 1 : execute(new Runnable()) ๊ณ ์ „์ ์ธ ๋ฐฉ๋ฒ•
executorService.execute(new Runnable() {
    @Override
    public void run() {
        System.out.println("1. Thread "+Thread.currentThread().getName());
    }
});

//์‚ฌ์šฉ๋ฐฉ๋ฒ• 2 : submit()
executorService.submit(()-> {
    System.out.println("2. Thread "+Thread.currentThread().getName());
});

/*
executorService๋Š” ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ณ ๋‚˜๋ฉด ๋‹ค์Œ ์ž‘์—…์ด ๋“ค์–ด์˜ฌ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ ๋Œ€๊ธฐํ•˜๋ฏ€๋กœ 
ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค -> ๋”ฐ๋ผ์„œ ๋ช…์‹œ์ ์œผ๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•ด์ค˜์•ผ ํ•œ๋‹ค
shutdown() _ gracefullํ•˜๋‹ค ์ฆ‰, ํ•˜๊ณ ์žˆ๋Š” ์ผ์„ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ์ข…๋ฃŒ
shutdownNow() _ noMercyํ•˜๋‹ค, ์ผ์˜ ๋งˆ๋ฌด๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ์ข…๋ฃŒ
 */
 
executorService.shutdown();

4. ์›ํ•˜๋Š” Thread Pool ๊ฐœ์ˆ˜๋กœ ์ œํ•œํ•˜๊ธฐ

//2๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ๊ณ ์ •์“ฐ๋ ˆ๋“œ ๊ฐœ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(getRunnable("Hello"));
executorService.submit(getRunnable("woonsik"));
executorService.submit(getRunnable("the"));
executorService.submit(getRunnable("java"));
executorService.submit(getRunnable("Thread"));

executorService.shutdown();

private static Runnable getRunnable(String string) {
	return ()-> System.out.println(string + Thread.currentThread().getName());
}

/*
์–ด๋–ป๊ฒŒ 2๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋กœ 5๊ฐœ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰?

๋ฉ”์ธ์—์„œ executor service์— 5๊ฐœ์˜ ์ž‘์—…์„ ๋ณด๋‚ธ๋‹ค
-> Thread pool์—๋Š” 2๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์กด์žฌ && Blocking Queue๊ฐ€ ์กด์žฌ
-> ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ฐ”์˜๋ฉด ๋‚˜๋จธ์ง€๋Š” blocking queue์—์„œ ๊ธฐ๋‹ค๋ฆฌ๊ณ ์žˆ๋‹ค๊ฐ€ ์ˆ˜ํ–‰์ด ๋œ๋‹ค

5. ScheduleExecutorService

โ†’ ExecutorService๋ฅผ ์ƒ์†๋ฐ›์€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ํŠน์ • ์‹œ๊ฐ„ ์ดํ›„

โ†’ ๋˜๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ.

System.out.println("์‹ฑ๊ธ€์“ฐ๋ ˆ๋“œ ์“ฐ์ผ€์ฅดexecutors");
ScheduledExecutorService executorService = 
	Executors.newSingleThreadScheduledExecutor();

//3์ดˆ ๋Œ€๊ธฐ ํ›„ ์ถœ๋ ฅ (Runnable command, long delay, TimeUnit unit) <- ๋งค๊ฐœ๋ณ€์ˆ˜
executorService.schedule(getRunnable("Hello"), 3, TimeUnit.SECONDS);
executorService.shutdown();

//ํŠน์ • ์‹œ๊ฐ„๋งˆ๋‹ค ๋ฐ˜๋ณต - 1์ดˆ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ 2์ดˆ๋งˆ๋‹ค ๋ฐ˜๋ณต (command, initial delay, 
		period, TimeUnit unit)
executorService.scheduleAtFixedRate(getRunnable("hello"), 
		1, 2, TimeUnit.SECONDS);