
์ค๋ ์ฃผ์ ์ฌํญ (5/26, ๊ธ์์ผ)
- Java ํ์ต
- Thread
Thread ๊ตฌํThread ํด๋์ค๋ฅผ ์์ ๋ฐ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ฏธ ๊ตฌํ๋์ด์๋ Thread ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ ์ฐ๋ ๋๋ฅผ ๊ตฌํํ ์ ์๋ค. Thread ํด๋์ค๋ฅผ ์์ ๋ฐ์ ํ,run() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํ ์ ์๋๋ฐ, ์ด run() ๋ฉ์๋์ ์์ฑ๋ ์ฝ๋๊ฐ ์ฐ๋ ๋์์ ์ํ๋๋ค.
public class TestThread extends Thread {
@Override
public void run() {
// Thread๊ฐ ์ํํ ์์
}
}
๋ง๋ค์ด์ง TestThread ํด๋์ค๋ฅผ ์ธ์คํด์คํ ์ํค๋ฉด ์ธ๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
/* Main.java */
// ์ฐ๋ ๋ ๊ฐ์ฒด ์์ฑ
TestThread thread = new TestThread();
// ์ฐ๋ ๋ ์คํ
thread.start();
Runnable ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒJava์์ ์ ๊ณตํ๋ Runnable ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๋ ๋๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์์ Thread ํด๋์ค๋ฅผ ์์ ๋ฐ์์ ์ฐ๋ ๋๋ฅผ ๊ตฌํํ๋ ๊ฒ๋ณด๋ค ๋ ๋ง์ด ์ฌ์ฉ๋๋ค. ์๋ฐ๋ ๋ค์ค์์์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋ค์ค์์ ๋ฏธ์ง์์ด๋ผ๋ ๋จ์ ์ ๋ณด์ํ ์ ์๋ค.
public class TestRunnable implements Runnable {
@Override
public void run() {
// Thread๊ฐ ์ํํ ์์
}
}
/* Main.java */
// Runnable ๊ฐ์ฒด ์์ฑ
Runnable run = new TestRunnable();
// Thread ๊ฐ์ฒด ์์ฑ, ์์ฑ์์ ๋งค๊ฐ๋ณ์๋ก Runnable์ ์ ๋ฌ
Thread thread = new Thread(run);
// ์ฐ๋ ๋ ์คํ
thread.start();
Runnable + ๋๋ค์์์ง ๋๋ค์์ ๋ํด ๋ฐฐ์ฐ์ง ์์์ง๋ง ๊ฐ๋ณ๊ฒ ์ดํด๋ณด์.
Runnable ๊ฐ์ฒด๋ฅผ ์์ฑํจ๊ณผ ๋์์, ๋๋ค์์ ์ฌ์ฉํ๋ค. ์์ 2)์์ Runnable.run()์ ์์ฑํ๋ ๊ตฌ๋ฌธ๋ค์ด ๋๋ค์ ๋ด๋ถ์ ๋ค์ด๊ฐ๋ค. ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ์์ฑํด์ Runnable.run()์ ์์ฑํ ํ์๊ฐ ์์ด์ง ๊ฒ์ด๋ค. (์ ์ด๋ ์ด ์ฝ๋ ์์์๋)
public class Main {
public static void main(String[] args) {
/* ์ด task ๋ถ๋ถ์ด ๋๋ค์ */
// ๊ธฐ์กด Runnable.run() ๋ฉ์๋์ ๋ฃ์ ์คํ๋ฌธ์
// ์ฌ๊ธฐ์ ๋์ ์์ฑํ๋ค๊ณ ๋ณผ ์ ์๋ค.
/* ๊ฐ์ฒด ์์ฑ๊ณผ ๋์์ ์คํ๋ฌธ ์์ฑ */
Runnable task = () -> {
// Thread๊ฐ ์ํํ ์์
...
// ์ฐ๋ ๋ ๋น๊ต๋ฅผ ์ํ
for(int i = 0; i < 5; i++) {
// ์ฐ๋ ๋ ์ด๋ฆ ์ถ๋ ฅ
System.out.print(Tread.currentThread().getName());
}
};
// Thread ๊ฐ์ฒด ์์ฑ, Runnable ๊ฐ์ฒด๋ฅผ ์ ๋ฌ
Thread thread1 = new Thread(task);
// thread ์ด๋ฆ ์ค์
thread1.setName("thread1");
Thread thread2 = new Thread(task);
thread2.setName("thread2");
// ์ฐ๋ ๋ ์คํ
thread1.start();
thread2.start();
}
}
์ด ์์ ์๋ ๋ฉํฐ์ฐ๋ ๋๋ก ์์ฑ๋์๋ค. ์ถ๋ ฅ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ฐ๋ ๋ ์ด๋ฆ์ด ๋ฒ๊ฐ์ ๊ฐ๋ฉด์ ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
thread1
thread1
thread2
thread1
thread2
thread2
thread1
thread1
thread2
thread2
๋ณด์ด์ง ์๋ ๊ณณ(background)์์ ์คํ๋๋, ๋ฎ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง ์ฐ๋ ๋๋ฅผ ๋งํ๋ค. ๋ณด์กฐ์ ์ธ ์ญํ ์ ๋ด๋นํ๋ฉฐ, ๋ํ์ ์ธ ๋ฐ๋ชฌ ์ฐ๋ ๋๋ก๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ ๋ฆฌํด์ฃผ๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ(Garbage Collector, GC)๊ฐ ์๋ค.
๋ฐ๋ชฌ ์ฐ๋ ๋๋ฅผ ๋ง๋๋ ๊ณผ์ ๋ ์์์ ์งํํ๋ ์ฐ๋ ๋ ๊ตฌํ ์์ ๋ค๊ณผ ์ ์ฌํ๋ค. Runnable ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ์ฐ๋ ๋์์ ์คํํ ๊ตฌ๋ฌธ์ ์์ฑํ๊ณ , Thread ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ฐ ๋ค์ Thread.setDaemon({Boolean}) ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ฐ๋ชฌ ์ฐ๋ ๋ ์ฌ๋ถ๋ฅผ ์ค์ ํ๊ณ , ์ฐ๋ ๋๋ฅผ ์คํํ๋ค. ์์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
public static void main(String[] args) {
// ๋ฌ๋๋ธ ์์ฑ ๋ฐ ๊ตฌํ
Runnable daemon = () -> {
for(int i = 0; i < 100; i++) {
System.out.println("demon: "+i);
}
// ๋ฐ๋ชฌ ์ฐ๋ ๋ ์์ฑ ๋ฐ ๋ฌ๋๋ธ ์ ๋ฌ
Thread thread = new Thread(daemon);
// ๋ฐ๋ชฌ ์ฐ๋ ๋ ์ฌ๋ถ ์ค์
thread.setDaemon(true);
// ์ฐ๋ ๋ ์คํ
thread.start();
// ์ฐ์ ์์ ๋น๊ต๋ฅผ ์ํ for๋ฌธ ์คํ
for(int i = 0; i < 5; i++) {
System.out.println("task");
}
}
๋ฐ๋ชฌ ์ฐ๋ ๋๋ ์ฐ์ ์์๊ฐ ๋ฎ๊ธฐ ๋๋ฌธ์, ์๋์ ์ผ๋ก ๋ค๋ฅธ ์ฐ๋ ๋๋ค์ ๋นํด ๋ฆฌ์์ค๋ฅผ ์ ๊ฒ ํ ๋น๋ฐ๋๋ค. ์ฌ์ง์ด ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋ชจ๋ ์ข
๋ฃ๋๋ฉด, ๋ฐ๋ชฌ ์ฐ๋ ๋๋ ๊ฐ์ ์ข
๋ฃ ๋นํ๊ธฐ ๋๋ฌธ์, 100๋ฒ ์ถ๋ ฅ๋์ด์ผํ์ "demon: "+i๋ ์ถ๋ ฅ ๋์ค์ ๋๊ฒจ๋ฒ๋ฆฐ๋ค.
task
task
task
demon: 1
demon: 2
task
task
demon: 3
๋ณด์ด๋ ๊ณณ(foregorund) ์์ ์คํ๋๋ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง ์ฐ๋ ๋๋ก, ํ๋ก๊ทธ๋จ ๊ธฐ๋ฅ์ ๋ด๋นํ๋ค. ๋ํ์ ์ธ ์ฌ์ฉ์ ์ฐ๋ ๋๋ก๋ ๋ฉ์ธ ์ฐ๋ ๋๊ฐ ์๋ค. JVM์ ์ฌ์ฉ์ ์ฐ๋ ๋์ ์์
์ด ๋๋๋ฉด ๋ฐ๋ชฌ ์ฐ๋ ๋๋ ์๋์ผ๋ก ์ข
๋ฃ์์ผ ๋ฒ๋ฆฐ๋ค.
(์์์ ๊ตฌํํ๋ ๊ฒ๋ค์ด ๋ชจ๋ ์ฌ์ฉ์ ์ฐ๋ ๋์ด๋ค.)
์ฐ๋ ๋๋ ์์ฑ๋ ๋ ์ฐ์ ์์๊ฐ ์ ํด์ง์ง๋ง, ์ค์๋์ ๋ฐ๋ผ์ ์ฐ๋ ๋์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ ์ ์๋ค. ์ฐ์ ์์๋ฅผ ๋๊ฒ ์ง์ ํ๋ฉด ๋ ๋ง์ ์์ ์๊ฐ์ ๋ถ์ฌ๋ฐ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋ค. ํ์ง๋ง ์ฐ์ ์์๊ฐ ๋๋ค๊ณ ๋ฐ๋์ ์ฐ๋ ๋๊ฐ ๋จผ์ ์ข ๋ฃ๋๋ ๊ฒ์ ์๋๋ค. ์์์ ๋ ๋ง์ด ๋ถ์ฌ๋ฐ์ผ๋, ๋จผ์ ์ข ๋ฃ๋ ํ๋ฅ ์ด ๋์์ง๋ ๊ฒ์ผ ๋ฟ์ด๋ค.
์ฐ์ ์์๋ ์๋์ ๊ฐ์ด 3๊ฐ์ง (์ต๋/์ต์/๋ณดํต) ์ฐ์ ์์๋ก ๋๋๋ค.
- ์ต๋ ์ฐ์ ์์ (MAX_PRIORITY) = 10
- ์ต์ ์ฐ์ ์์ (MIN_PRIORITY) = 1
- ๋ณดํต ์ฐ์ ์์ (NROM_PRIORITY) = 5 (๊ธฐ๋ณธ๊ฐ)
์ฐ์ ์์๋ setPriority() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์๋ค.
Thread thread1 = new Thread(task1);
thread1.setPriority(8);
getPriority() ๋ฉ์๋๋ ํ์ฌ ์ฐ์ ์์๋ฅผ ๋ฐํํ๋ค. ์ด๋ฅผ ํตํด ํ์ฌ ์ฐ์ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
int threadPriority = thread1.getPriority();
System.out.println("threadPriority = " + threadPriority);
์๋ก ๊ด๋ จ์ด ์๋ ์ฐ๋ ๋๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ ๋ค๋ฃฐ ์ ์๋ค. ์ฐ๋ ๋๋ค์ ๋ชจ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ทธ๋ฃน์ ํฌํจ๋์ด์๋๋ฐ, JVM์ด ์คํ๋๋ฉด system ๊ทธ๋ฃน์ด ์์ฑ๋๊ณ , ์ฐ๋ ๋๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก system ๊ทธ๋ฃน์ ํฌํจ๋๋ค. ๋ชจ๋ ์ฐ๋ ๋๋ค์ ๋ฐ๋์ ํ๋์ ๊ทธ๋ฃน์ ํฌํจ๋์ด ์์ด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
๏ผ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ์ง์ ๋ฐ์ง ๋ชปํ ์ฐ๋ ๋๋ ์์ ์ ์์ฑํ ๋ถ๋ชจ ์ฐ๋ ๋์ ๊ทธ๋ฃน๊ณผ ์ฐ์ ์์๋ฅผ ์์๋ฐ๊ฒ ๋๋๋ฐ, ์ฐ๋ฆฌ๊ฐ ์์ฑํ๋ ์ฐ๋ ๋๋ค์ main ์ฐ๋ ๋ ํ์์ ํฌํจ๋๋ค.
ThreadGroup ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ , Thread ๊ฐ์ฒด ์์ฑ ์์ ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ๋ค.
/* 1. ThreadGroup ํด๋์ค๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. */
ThreadGroup group1 = new ThreadGroup("Group1");
/* 2. Thread ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด์ ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ๋ค. */
// Thread(ThreadGroup group, Runnable target, String name)
Thread thread1 = new Thread(group1, task, "Thread 1");
/* 3. Thread์ ThreadGroup์ด ํ ๋น๋๊ฒ์ ํ์ธํ ์ ์๋ค. */
System.out.println("Group of thread1 : " + thread1.getThreadGroup().getName());
[์คํ๋๊ธฐ ์ํ]
ThreadGroup ๊ฐ์ฒด์ interrupt() ๋ฉ์๋๋ฅผ ์คํ์ํค๋ฉด, ํด๋น ๊ทธ๋ฃน ์ฐ๋ ๋๋ค์ด ์คํ๋๊ธฐ ์ํ๋ก ๋ณ๊ฒฝ๋๋ค.
/* 1. ThreadGroup ํด๋์ค๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค. */
ThreadGroup group1 = new ThreadGroup("Group1");
/* 2. Thread ๊ฐ์ฒด ์์ฑ์ ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ๋ฃ์ด์ค๋ค. */
// Thread(ThreadGroup group, Runnable target, String name)
Thread thread1 = new Thread(group1, task, "Thread 1");
Thread thread2 = new Thread(group1, task, "Thread 2");
/* 3. interrupt()๋ ์ผ์์ ์ง ์ํ์ธ ์ฐ๋ ๋๋ฅผ ์คํ๋๊ธฐ ์ํ๋ก ๋ง๋ ๋ค. */
group1.interrupt();