์ค๋ ์ฃผ์ ์ฌํญ (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();