[java] Thread
in Java
Thread
์ฐ๋ ๋์ ๊ฐ๋ ๋ฐ ๊ธฐ๋ณธ ์์
ํ๋ก์ธ์ค์ ์ฐ๋ ๋
ํ๋ก์ธ์ค
์ด์์ฒด์ ์์๋ ์คํ์ค์ธ ํ๋์ ์ดํ๋ฆฌ์ผ์ด์ ์ ํ๋ก์ธ์ค๋ผ๊ณ ํจ.
์ด์์ฒด์ ๋ก๋ถํฐ ์คํ์ ํ์ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋น๋ฐ์ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฝ๋๋ฅผ ์คํ.
์ฐ๋ ๋
ํ๋ก์ธ์ค๋ฅผ ์ด๋ฃจ๋ ์ฝ๋์ ์คํํ๋ฆ.
ํ๋์ ์ฐ๋ ๋๋ ํ๋์ ์ฝ๋ ์คํํ๋ฆ์.
๋ฉํฐ ํ๋ก์ธ์ค
์๋ก ๋ ๋ฆฝ์ . ํ๋์ ํ๋ก์ธ์ค์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ํฅ์ ๋ฏธ์น์ง ์์.
๋ฉํฐ ์ฐ๋ ๋
ํ๋์ ํ๋ก์ธ์ค ๋ด๋ถ์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ํ๋์ ์ฐ๋ ๋๊ฐ ์์ธ๋ฅผ ๋์ง๋ฉด ํ๋ก์ธ์ค ํ๋๊ฐ ์์ ๋์ํ์ง ์์ ์ ์์ -> ์์ธ ์ฒ๋ฆฌ ์ค์.
๋ฉ์ธ ์ฐ๋ ๋
์๋ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฉ์ธ์ฐ๋ ๋๊ฐ main ๋ฉ์๋๋ฅผ ์คํํ๋ฉด์ ์์ํจ.
์ฐ๋ ๋์ ์์ฑ
1.Thread ํด๋์ค๋ก๋ถํฐ ์ง์ ์์ฑ
Thread thread = new Thread(Runnable target);
- ์ง์ ์์ฑํ๊ธฐ ์ํด์๋ Runnable ํ์ ์ ๋งค๊ฐ๊ฐ์ผ๋ก ๊ฐ๋ ์์ฑ์๋ฅผ ํธ์ถํด์ผํจ.
- Runnable์ ์ธํฐํ์ด์ค ํ์ ์ธ๋ฐ run ๋ฉ์๋๊ฐ ์ ์ธ๋์ด ์์ด Runnable ๊ตฌํ๊ฐ์ฒด๋ run ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผํจ.
- Runnable ๊ตฌํ๊ฐ์ฒด๋ฅผ ์ง์ Class๋ก ์ ์ํด์ ์ฌ์ฉํ๊ฑฐ๋ ์ต๋ช ๊ฐ์ฒด๋ฅผ ์ด์ฉ(์ฃผ๋ก ์ด๋ค๊ณ ํจ.)ํ๋ ๋ฐฉ๋ฒ์ด ์์.
- ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํด์๋ run ๋ฉ์๋ ํธ์ถ์ด ์๋ start()๋ฅผ ํธ์ถํด์ผํจ.
Runnable taskrun = new Task();
Thread thread = new Thread(taskrun);
Thread threadanony = new Thread( new Runnable(){
public void run(){
//์ฐ๋ ๋๊ฐ ์คํํ ์ฝ๋ํ๋ฆ
}
});
2.Thread ํ์ ํด๋์ค๋ก๋ถํฐ ์์ฑ.
- Thread ํด๋์ค๋ฅผ ์์ํด์ผํจ.
import java.awt.Toolkit;
public class BeepThread extends Thread{
@Override
public void run() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for(int i =0; i<5; i++) {
toolkit.beep();
try {Thread.sleep(500);} catch(Exception e) {}
}
}
}
- 0.5์ด๋ง๋ค ๋นํ์๋ฆฌ๋ฅผ ๋ด๋ ์ฐ๋ ๋ ํ์ ํด๋์ค ์์ฑ.
import java.awt.Toolkit;
public class BeepPrintExample3 {
public static void main(String[] args) {
Thread thread = new BeepThread();
//2. ใ
์ต๋ช
๊ฐ์ฒด
Thread thread2 = new Thread() {
@Override
public void run() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for(int i =0; i<5; i++) {
toolkit.beep();
try {Thread.sleep(500);} catch(Exception e) {}
}
}
};
thread2.start();
for(int i =0; i<5; i++) {
System.out.println("๋ต");
try {Thread.sleep(500);} catch(Exception e) {}
}
}
}
- ๋ต ์ถ๋ ฅ๊ณผ ๋ต ๋นํ์์ด ๊ฑฐ์ ๋์์ ์ํ๋๋๊ฒ์ฒ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฒ.
์ฐ๋ ๋์ ์ด๋ฆ ์ ์
- ์ฐ๋ ๋๋ ์ฐ๋ ๋๋ง๋ค ์ด๋ฆ์ด ์์.
- ํฐ ์ญํ ์ ํ์ง๋ ์์ง๋ง ๋๋ฒ๊น ํ ๋ ์ด๋ค ์ฐ๋ ๋๊ฐ ์๋ฌ๋ฅผ ๋ด๋์ง ์กฐ์ฌํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ค๊ณ ํจ.
- ์ด๋ฆ์ ์ฃผ์ง ์์ ์ฐ๋ ๋๋ โThread-nโ์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ์ค์ ๋จ.
- setName(โ์ฐ๋ ๋์ด๋ฆโ) ์ผ๋ก ์ฐ๋ ๋๋ช ์ ์ค์ ๊ฐ๋ฅ.
- getName() ๋ฉ์๋๋ก ์ฐ๋ ๋ ์ด๋ฆ์ ๋ฐํ.
thread.setName("์ฐ๋ ๋๋ช
");
thread.getName(); // ์ฐ๋ ๋๋ช
๋ฐํ
- currentThread()๋ก ํ์ฌ ์ฝ๋๋ฅผ ์คํํ๊ณ ์๋ ์ฐ๋ ๋์ ์ฐธ์กฐ๋ฅผ ์ป์ด์ฌ ์ ์์
Thread thread = Thread.currentThread();
๊ฐ๋จ ์์
public class ThreadNameExample {
public static void main(String[] args) {
Thread mainThread = Thread.currentThread();
System.out.println("ํ๋ก๊ทธ๋จ ์์ ์ฐ๋ ๋ ์ด๋ฆ: "+mainThread.getName());
ThreadA threadA = new ThreadA();
System.out.println("์์
์ฐ๋ ๋ ์ด๋ฆ : "+threadA.getName());
threadA.start();
ThreadB threadB = new ThreadB();
System.out.println("์์
์ฐ๋ ๋ ์ด๋ฆ : "+threadB.getName());
threadB.start();
}
}
//-----------------------------------
public class ThreadA extends Thread{
public ThreadA() {
setName("ThreadA");
}
@Override
public void run() {
for(int i =0; i<2; i++) {
System.out.println(getName()+"๊ฐ ์ถ๋ ฅํ ๋ด์ฉ");
}
}
}
//-----------------------------------
public class ThreadB extends Thread{
@Override
public void run() {
for(int i =0; i<2; i++) {
System.out.println(getName()+"๊ฐ ์ถ๋ ฅํ ๋ด์ฉ");
}
}
}
์ฐ๋ ๋์ ์ฐ์ ์์ ๊ฐ๋
์ฐ๋ ๋์ ์ฐ์ ์์
๋์์ฑ : ๋ฉํฐ์์ ์ ์ํด ํ๋์ ์ฝ์ด์์ ๋ฉํฐ ์ฐ๋ ๋๊ฐ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํํ๋ ์ฑ์ง
๋ณ๋ ฌ์ฑ : ๋ฉํฐ์์ ์ ์ํด ๋ฉํฐ ์ฝ์ด์์ ๊ฐ๋ณ ์ฐ๋ ๋๋ฅผ ๋์์ ์คํํ๋ ์ฑ์ง
์ฐ๋ ๋ ์ค์ผ์ค๋ง
- ์ฐ๋ ๋์ ๊ฐฏ์๊ฐ ์ฝ์ด์ ์๋ณด๋ค ๋ง์ ๊ฒฝ์ฐ์ ์ฐ๋ ๋๋ฅผ ์ด๋ค ์์์ ์ํด ๋์์ฑ์ผ๋ก ์คํํ ๊ฒ์ธ๊ฐ์ ๋ํ ๊ณํ.
- ์์ฃผ ์งง์ ์๊ฐ ์ฐ๋ ๋์ run ๋ฉ์๋๋ฅผ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํํ๋ค.
##### ์ฐ์ ์์(priority)๋ฐฉ์
- ์ฐ์ ์์๊ฐ ๋์ ์ฐ๋ ๋๊ฐ ์คํ์ํ๋ฅผ ๋ ๋ง์ด ๊ฐ์ ธ๊ฐ.
- ๊ฐ์ฒด์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ ์ด๊ฐ๋ฅ.
- 1๋ถํฐ 10๊น์ง ์ฐ์ ์์, ๋์ผ๋ฉด ๋จผ์ ์คํ
thread.setPriority(์ฐ์ ์์);
์ฐ์ ์์ ์์ : Thread.MAX_PRIORITY(10), Thread.NORM_PRIORITY(5), Thread.MIN_PRIORITY(1)
- ์ฐ์ ์์๊ฐ ๋์ ์ฐ๋ ๋๊ฐ ์คํ๊ธฐํ๋ฅผ ๋ ๋ง์ด ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ์ฐ์ ์์๊ฐ ๋ ๋ฎ์ ์ฐ๋ ๋๋ณด๋ค ๊ฐ์ ์์ ์ด๋ผ๋ ๋นจ๋ฆฌ ๋๋ผ ์ ์๋ค.
- ํ์ง๋ง ์ฟผ๋ ์ฝ์ด์ผ ๊ฒฝ์ฐ ์ฐ๋ ๋๊ฐ 4๊ฐ ๋ณด๋ค ์ ์ ๊ฒฝ์ฐ๋ ์ฐ์ ์์๊ฐ ํฌ๊ฒ ์ํฅ์ ๋ฏธ์น์ง ๋ชปํ๋ค. 5๊ฐ์ด์์ผ๋ ์ฐ์ ์์ ๋ฐฉ์์ด ํจ๊ณผ๋ฅผ ๋ณด๊ฒ ๋๋ค.
public class PriorityExample {
public static void main(String[] args) {
for(int i =1; i<=10; i++) {
Thread thread = new ClacThread("thread"+i);
if(i == 10) {
//๊ฐ์ฅ ๋ฎ์ ์ฐ์ ์์
thread.setPriority(Thread.MAX_PRIORITY);
}else {
//๊ฐ์ฅ ๋์ ์ฐ์ ์์
thread.setPriority(Thread.MIN_PRIORITY);
}
thread.start();
}
}
}
//---------------------------------------------------------
public class ClacThread extends Thread{
public ClacThread(String name) {
setName(name);
}
public void run() {
for(int i =0; i<2000000000; i++) {}
System.out.println(getName());
}
}
์ํ ํ ๋น(Round-robin) ๋ฐฉ์
- ์๊ฐํ ๋น๋(Time Slice)์ ์ ํด ํ๋์ ์ฐ๋ ๋๋ฅผ ์ ํด์ง ์๊ฐ๋งํผ๋ง ์คํํ๋๋ก ํ๋ ๋ฐฉ์.
- JVM์ ์ํด์ ์ ํด์ง๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ก ์ ์ด ๋ถ๊ฐ๋ฅ
์ฐ๋ ๋ ๋๊ธฐํ ๋ฉ์๋, ๋๊ธฐํ ๋ธ๋ญ
๊ณต์ ๊ฐ์ฒด ์ฌ์ฉ์
- ์ฑ๊ธ ์ฐ๋ ๋์ ๊ฒฝ์ฐ๋ ๊ณ ๋ฏผํ ๊ฒฝ์ฐ๊ฐ ๊ฑฐ์ ์๋ค.
- ๋ฉํฐ ์ฐ๋ ๋์ ๊ฒฝ์ฐ ์ฐ๋ ๋๊ฐ์ ํ๋์ ๊ฐ์ฒด ๊ณต์ ์ ๋๋ฒ๊น ํ๊ธฐ ์ด๋ ค์ด ์ค๋ฅ๊ฐ ๋ํ๋ ์ ์๋ค.
Tread-1์ด ๊ณต์ ๊ฐ์ฒด์ ๋ฉค๋ฒ๋ณ์์ ํ ๋น๋ ๊ฐ์ ๋ณ๊ฒฝ. -> ๊ทธ์ฌ์ด Thread-2๊ฐ ๊ณต์ ๊ฐ์ฒด์ ๋ฉค๋ฒ๋ณ์์ ํ ๋น๋ ๊ฐ์(null์ด ์๋์ง ๋ชจ๋ฅด๊ณ ) ์์ด์นจ. -> Thread-1 ๊ณต์ ๊ฐ์ฒด ์ฌ์ฉํ๋ ค๋๋ฐ ๊ฐ์ด๋ฐ๋-> ์ค๋ฅ
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋จ ํ๋์ ์ฐ๋ ๋๋ง์ ์คํํ ์ ์๋ ์๊ณ์์ญ์ ์ง์ ํด์ผ ํ๋ค. ์ฆ, ๊ฐ์ฒด์ ์ ๊ธ์ ๊ฑธ์ด๋์ด ํ๋์ ์ฐ๋ ๋๋ง์ด ์ ๊ทผ๊ฐ๋ฅํ๊ณ ๋๋จธ์ง ์ฐ๋ ๋๋ ๋๊ธฐํ๋๋ก ๋ง๋ ๋ค.
ํค์๋ : synchronized
๋๊ธฐํ(synchronized) ๋ฉ์๋
public synchronized void method(){
//์๊ณ์์ญ; ๋จํ๋์ ์ฐ๋ ๋๋ง ์คํ๊ฐ๋ฅ.
}
package sync;
public class Calculator {
private int memory;
public int getMemory() {
return memory;
}
//๋๊ธฐํ ๋ฉ์๋๋ก ์ ์ธํ๋ ๋ฐฉ๋ฒ
public synchronized void setMemory(int memory) {
this.memory = memory;
try {
Thread.sleep(2000);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+" : "+this.memory);
}
}
- setMemory ๋ฉ์๋๋ ํ๋์ ์ฐ๋ ๋๋ง์ด ์คํ ๊ฐ๋ฅํ ๋ฉ์๋
๋๊ธฐํ(synchronized) ๋ธ๋ญ
public void method(){
synchronized (๊ณต์ ๊ฐ์ฒด){
//์๊ณ์์ญ(๋จ ํ๋์ ์ฐ๋ ๋๋ง ์คํ ๊ฐ๋ฅ)
}
//์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ์คํ ๊ฐ๋ฅํ ์์ญ.
}
package sync;
public class Calculator {
private int memory;
public int getMemory() {
return memory;
}
// ์ด๋ ๊ฒ ๋๊ธฐํ ๋ธ๋ญ์ ์ฌ์ฉํด์ ์ฒ๋ฆฌํ ์ ์๋ค.
public void setMemory(int memory) {
synchronized (this) {
this.memory = memory;
try {
Thread.sleep(2000);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+" : "+this.memory);
}
}
}
์ฐ๋ ๋์ ์ํ์ ์ด ๋ฉ์๋ ๋ฐ ๋ฐ๋ชฌ ์ฐ๋ ๋ ๊ฐ๋
์ฐ๋ ๋์ ์ํ์ ์ด
- ์คํ์ค์ธ ์ฐ๋ ๋์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ.
- ๋ฉ์๋๋ก ์ฃผ๋ก ์ ์ด
- interrupt(), sleep(), join(), wait(), yield() notify(), notifyAll() ๋ฑ์ ๋ฉ์๋๊ฐ ์กด์ฌ.
- ์ด์ค notify(), notifyAll(), wait() ๋ฉ์๋๋ Object ํด๋์ค์ ๋ฉ์๋์ด๊ณ ๋๋จธ์ง๋ Thread ํด๋์ค์ ๋ฉ์๋.
์ผ์ ์๊ฐ๋์ ์ผ์์ ์ง : sleep()
- ์คํ์ค์ธ ์ฐ๋ ๋๋ฅผ ์ผ์์ ์ง.
- ๋งค๊ฐ๊ฐ์ผ๋ก ๋ฐ๋ฆฌ์ด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ํด๋น ์๊ฐ๋์ sleep() ๋ฉ์๋๋ฅผ ๋ง๋๋ ์ฐ๋ ๋๋ ์ผ์์ ์งํจ.
- ์ผ์์ ์ง ์ํ์์ interrupt() ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ InterruptedException์ด ๋ฐ์๋จ.
try{
Thread.sleep(1000); //1์ด๊ฐ ์ผ์์ ์ง(๋ฐ๋ฆฌ์ด : 1000 -> 1์ด)
}catch(InterruptedException){
//interrupt() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด ์คํ.
}
ํ ์ฐ๋ ๋์ ์คํ ์๋ณด : yield()
- ์ฐ๋ ๋๊ฐ ์ฒ๋ฆฌํ๋ ๋ฐ๋ณต์์ ์ ์ํด for๋ฌธ์ด๋ while๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์.
public void run(){
while(true){
if(work){
System.out.println("ThreadA ์์
๋ด์ฉ");
}
}
}
-์ด๋ while๋ฌธ์ boolean ํ์ work ๋ณ์๊ฐ false ์ผ๊ฒฝ์ฐ์๋ ์ธ๋ฐ์๋ ๋ฃจํ๋ฅผ ๋๊ฒ๋จ.
- yield() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ํธ์ถํ ์ฐ๋ ๋๋ ์คํ๋๊ธฐ์ํ๋ก ๋์๊ฐ๊ณ ๋์ผํ ์ฐ์ ์์ ํน์ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ๋ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ์คํ ๊ธฐํ๋ฅผ ๊ฐ๊ฒ๋จ.
public class ThreadA extends Thread{
public boolean stop = false; //์ข
๋ฃ ํ๋๊ทธ
public boolean work = true; // ์์
์งํ์ฌ๋ถ
public void run() {
while(!stop) {
if(work) {
System.out.println("ThreadA ์์
๋ด์ฉ");
}else {
Thread.yield();
}
}
System.out.println("ThreadA ์ข
๋ฃ");
}
}
- ThreadA๊ฐ else ๋ฌธ์ผ๋ก yield ๋ฉ์๋๋ฅผ ๋ง๋๋ฉด ํ์ฌ Thread ๊ฐ์ฒด์ธ ThreadA์ run ๋ฉ์๋๋ ์คํ๋๊ธฐ ์ํ๊ฐ ๋๊ณ ThreadB๊ฐ ์คํ๊ธฐํ๋ฅผ ๊ฐ๋๋ค.
๋ค๋ฅธ ์ฐ๋ ๋์ ์ข ๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ : join()
- ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ์ข ๋ฃ๋์ด์ผ ์คํํด์ผํ๋ ์ฐ๋ ๋๊ฐ ์กด์ฌ
- ๊ณ์ฐ์์ ์ด ๊ทธ ์์ธ๋ฐ, ๊ณ์ฐํ์ฌ ๊ฒฐ๊ณผ๋ฅผ return ํ๋ ์ฐ๋ ๋๊ฐ ์กด์ฌํ๋ฉด ๊ทธ๊ฒ์ ์ถ๋ ฅํ๋ ์ฐ๋ ๋๊ฐ ํ์ํ๋ฐ
- ๊ทธ ๋ ์ถ๋ ฅ์ฐ๋ ๋๊ฐ ๋จผ์ ์ํ๋๋ฉด ์ค๋ฅ์.
public class SumThread extends Thread{
private long sum;
public long getSum() {
return sum;
}
public void setSum(long sum) {
this.sum = sum;
}
public void run() {
for(int i =1; i<=100; i++) {
sum+=i;
}
}
@Override
public String toString() {
return "SumThread [sum=" + sum + "]";
}
}
public class JoinExample {
public static void main(String[] args) {
SumThread sumThread = new SumThread();
sumThread.start();
try {
sumThread.join();//ํ์ฌ ์ฐ๋ ๋ ๊ธฐ์ค (์ด๋ถ๋ถ์ ์ฃผ์์ฒ๋ฆฌํด์ ๊ฒฐ๊ณผ๋ฅผ ๋น๊ตํด๋ณด์ธ์)
} catch (Exception e) {
}
System.out.println("1~100 ํฉ : "+sumThread.getSum());
}
}
- ์ฌ๊ธฐ์ ์ถ๋ ฅ์ฐ๋ ๋๋ ๋ฉ์ธ์ฐ๋ ๋๊ฐ ๋ด๋นํ ๊ฒ์.
์ฐ๋ ๋๊ฐ ํ๋ ฅ : wait() , notify() , notifyAll()
- ๋๊ฐ์ ์ฐ๋ ๋๋ฅผ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํ
- ํต์ฌ์ ๊ณต์ ๊ฐ์ฒด์ ํ์ฉ
- ๋ ์ฐ๋ ๋๊ฐ ์์ ํ ๋ด์ฉ์ ๋๊ธฐํ ๋ฉ์๋๋ก ๊ตฌ๋ถ.
- ์ฐ๋ ๋1 ์์ ์๋ฃ -> notify() ๋ฉ์๋ ํธ์ถ -> (์ผ์์ ์ง)์ฐ๋ ๋ 2 ์คํ๋๊ธฐ์ํ๋ก ๋ณ๊ฒฝ -> ์ฐ๋ ๋ 1์ wait() (์ผ์์ ์ง ์ํ)
- ์ด๋ค ๋ฉ์๋๋ ๋๊ธฐํ ๋ฉ์๋ ํน์ ๋๊ธฐํ ๋ธ๋ก์์๋ง ์ฌ์ฉ๊ฐ๋ฅ.
//๊ณต์ ๊ฐ์ฒด
public class WorkObject {
public synchronized void methodA() {
System.out.println("ThreadA์ methodA() ์์
์คํ");
notify(); //์ผ์์ ์ง ์ํ์ ์๋ ThreadB๋ฅผ ์คํ๋๊ธฐ ์ํ๋ก ๋ง๋ฌ.
try {
wait();//ThreadA๋ฅผ ์ผ์์ ์ง ์ํ๋ก ๋ง๋ฌ.
} catch (Exception e) {
}
}
public synchronized void methodB() {
System.out.println("ThreadB์ methodB() ์์
์คํ");
notify(); //์ผ์์ ์ง ์ํ์ ์๋ ThreadA๋ฅผ ์คํ๋๊ธฐ ์ํ๋ก ๋ง๋ฌ.
try {
wait();//ThreadB๋ฅผ ์ผ์์ ์ง ์ํ๋ก ๋ง๋ฌ.
} catch (Exception e) {
}
}
}
//Thread A
public class ThreadA extends Thread{
private WorkObject workObject;
public ThreadA(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i =0; i<10; i++) {
workObject.methodA();
}
}
}
//ThreadB
public class ThreadB extends Thread{
private WorkObject workObject;
public ThreadB(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i =0; i<10; i++) {
workObject.methodB();
}
}
}
//main ์ฐ๋ ๋
public class WaitNotifyExample {
public static void main(String[] args) {
WorkObject shareObject = new WorkObject(); //๊ณต์ ๊ฐ์ฒด ์์ฑ
ThreadA threadA = new ThreadA(shareObject);
ThreadB threadB = new ThreadB(shareObject);//ThreadA์ ThreadB ์์ฑ
threadA.start();
threadB.start();
}
}
- ๋ฉ์ธ ์ฐ๋ ๋์์ ๊ณต์ ๊ฐ์ฒด๋ฅผ ์์ฑ
- ๊ฐ๊ฐ์ ์ฐ๋ ๋์ ๋ฉค๋ฒ๋ณ์๋ก ์ด๊ธฐํ. ๊ณต์ ๊ฐ์ฒด์ methodA์ methodB๋ฅผ ์ฌ์ฉ
- methodA์ methodB๋ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํ๋์ด์ผํจ.
- ์ด ํ๋ ฅ๊ฐ๋ ์์ ๋ฐ์ ํ์ฌ ์ ๋ช ํ ์๋ฐ ๋์์ธ ํจํด์ธ ์์ฐ์ ์๋น์ ํจํด์ผ๋ก ์ฐ๊ฒฐ๋จ.
์ฐ๋ ๋์ ์์ ์ข ๋ฃ : interrupt()
- run() ๋ฉ์๋๊ฐ ๋ชจ๋ ์คํ๋๋ฉด ์ฐ๋ ๋๋ ์ข ๋ฃ๋จ.
- ๊ธฐ์กด์ stop() ์ด๋ ๋ฉ์๋๊ฐ ์ ๊ณต๋์์ผ๋ deprecated ๋์๋ค. -> ๋ฌธ์
- ์? -> ์ฐ๋ ๋๊ฐ ์ฌ์ฉํ๋ ์์์ด ๋ฌธ์ ๊ฐ ๋ ๊ฐ๋ฅ์ฑ( ์์์ด๋ ํ์ผ, ๋คํธ์ํฌ ์ฐ๊ฒฐ ๋ฑ)
- interrupt() ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์์๋ ํด์ ํ๋ฉฐ ์์ ํ๊ฒ ์ข ๋ฃํ ์ ์์.
public class PrintThread2 extends Thread{
public void run() {
try {
while(true) {
System.out.println("์คํ ์ค");
Thread.sleep(1);
//if(Thread.interrupted()) {
//if(Thread.currentThread().isInterrupted()) {
//break;
//}
}
} catch (InterruptedException e) {
System.out.println("interrupt() ์คํ");
}
System.out.println("์์ ์ ๋ฆฌ");
System.out.println("์คํ ์ข
๋ฃ");
}
}
//๋ฉ์ธ ์ฐ๋ ๋
public class InterruptExample {
public static void main(String[] args) {
Thread thread = new PrintThread2();
thread.start();
try {
Thread.sleep(1000);
} catch (Exception e) {
}
thread.interrupt();
}
}
- ๋ฉ์ธ์ฐ๋ ๋์์ interrupt() ๋ฉ์๋๊ฐ ํธ์ถํ ๋ PrintThread2 ์ฐ๋ ๋๋ InterruptedException์ด ๋ฐ์ํ๊ธฐ ์ํด์๋ ์ผ์์ ์ง์ํ์ ์์ด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฌด์๋ฏธ๊ฐ ์๋ค.
- ๊ทธ๋์ Thread.sleep(1) ์ฝ๋๋ก ํ๋ฒ ์ผ์์ ์ง ์ํ๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ ๋ฉ์ธ์ฐ๋ ๋์์ interrupt() ๋ฉ์๋๋ฅผ ์คํํ๊ณ ๋จผ์ ์ข ๋ฃํ์๊ธฐ ๋๋ฌธ์ ์ดํ PrintThread2 ์ฐ๋ ๋๋ ์์์ ์ ๋ฆฌํ๋ ์ฝ๋๋ฅผ ์คํํ๋ฉฐ ์์ ํ๊ฒ ์ข ๋ฃํ๊ฒ ๋๋ค.
- ์ฃผ์์ฒ๋ฆฌ๋ Thread.interrupted() ๋ฉ์๋์ isInterrupted() ๋ฉ์๋๋ ๋ชจ๋ interrupt() ๋ฉ์๋๊ฐ ์คํ๋ฌ๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํํ๋ boolean ๊ฐ์ด๋ค. ์ฐธ์กฐ๊ฐ์ฒด๋ฅผ ๋ณด๋ฉด์๊ฒ ์ง๋ง Thread.interrupted()๋ static ๋ฉ์๋์ด๊ณ , isInterrupted() ๋ฉ์๋๋ ์ธ์คํด์ค ๋ฉ์๋์ด๋ค. ๋์ค ์ด๋ค๊ฒ์ ์ฌ์ฉํด๋ ์ข๋ค.
๋ฐ๋ชฌ ์ฐ๋ ๋
- ์ฐ๋ ๋์ ์์ ์ ๋๋ ๋ณด์กฐ์ ์ธ ์ญํ ์ ์ํํ๋ ์ฐ๋ ๋.
- ์ฃผ ์ฐ๋ ๋๊ฐ ์ข ๋ฃ๋๋ฉด ๋ฐ๋ชฌ์ฐ๋ ๋๋ ๊ฐ์ ์ ์ผ๋ก ์๋ ์ข ๋ฃ.
- Java์ Garbage Collector๊ฐ ๋ํ์ ์ธ ๋ฐ๋ชฌ ์ฐ๋ ๋๋ผ๊ณ ํจ. - > JVM์ด ์ข ๋ฃ๋๋ฉด ๊ฐ์ด ์ข ๋ฃ๋๋๊น.
- ํ์ฌ ์ฐ๋ ๋์์ ๋ค๋ฅธ ์ฐ๋ ๋๋ฅผ ๋ฐ๋ชฌ์ฐ๋ ๋๋ก ๋ง๋ค๊ธฐ ์ํด์๋ ๋ฐ๋ชฌ ์ฐ๋ ๋๊ฐ๋ ์ฐ๋ ๋์ ์ฐธ์กฐ๊ฐ์ฒด์์ setDaemon(true)๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋๋ค.
- ์ฃผ์์ ์ ๋ฐ๋ชฌ์ฐ๋ ๋์ ์ฐ๋ ๋๊ฐ ์ด๋ฏธ start() ๋ฉ์๋๋ฅผ ํธ์ถํ ์ํ๋ผ๋ฉด IllegalThreadStateException์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ start() ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ์กด์ setDaemon(true)๋ฅผ ์คํํด์ผํ๋ค.
public class AutoSaveThread extends Thread{
public void save() {
System.out.println("์์
๋ด์ฉ์ ์ ์ฅํจ");
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("1");//์ฌ๊ธฐ์คํ์๋จ. exception ๋ฐ์์ ์๋
e.printStackTrace();
break;
}
save();
}
}
}
//๋ฉ์ธ ์ฐ๋ ๋
public class DaemonExample {
public static void main(String[] args) {
AutoSaveThread autoSaveThread = new AutoSaveThread();
autoSaveThread.setDaemon(true);
autoSaveThread.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("๋ฉ์ธ ์ฐ๋ ๋ ์ข
๋ฃ");
}
}
- ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด ๊ธฐ์กด์ ์ฐ๋ ๋๋ ๋ฉ์ธ ์ฐ๋ ๋๊ฐ ์ฃฝ์ด๋ ๋ฐ๋ณต์์ ์ ํ๋ ๊ฒฝ์ฐ๋ ์์ ์ฐ๋ ๋๋ ์ด์์์ด ํ๋ก๊ทธ๋จ์ด ์ฃฝ์ง ์์๋๋ฐ ์ ์์ ๋ ๋ฉ์ธ ์ฐ๋ ๋๊ฐ ์ฃฝ์ผ๋ฉด์ ๋ฐ๋ชฌ์ฐ๋ ๋๋ ๊ฐ์ด ์ฃฝ์ด์ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃ์ํจ๋ค.
์ฐ๋ ๋ ๊ทธ๋ฃน ๊ฐ๋
Thread Group
- ๊ด๋ จ๋ ์ฐ๋ ๋๋ฅผ ๋ฌถ์ด์ ๊ด๋ฆฌํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ.
- JVM์ด ์คํ๋ ๋ - system ์ฐ๋ ๋ ๊ทธ๋ฃน์ ๋ง๋ฌ - JVM ์ด์์ ํ์ํ ์ฐ๋ ๋๋ค์ ์์ฑ - system ์ฐ๋ ๋ ๊ทธ๋ฃน์ ํฌํจ์ํด
์ฐ๋ ๋ ๊ทธ๋ฃน ์ด๋ฆ ์ป๊ธฐ
ThreadGroup group = Thread.currentThread().getThreadGroup();
String groupName = group.getName();
์ฐ๋ ๋ ๊ทธ๋ฃน ์์
public static void main(String[] args) {
ThreadGroup group = Thread.currentThread().getThreadGroup();
//System.out.println(group.getName());
AutoSaveThread autoSaveThread = new AutoSaveThread();
autoSaveThread.setName("AutoSaveThread");
autoSaveThread.setDaemon(true);
autoSaveThread.start();
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
Set<Thread> threads = map.keySet();
for(Thread thread : threads) {
System.out.println("Name : "+thread.getName() + ((thread.isDaemon()) ? "(๋ฐ๋ชฌ)":"(์ฃผ)"));
System.out.println("\t"+"์์๊ทธ๋ฃน : "+thread.getThreadGroup().getName());
System.out.println();
}
}
- getAllStackTraces() : ํ๋ก์ธ์ค ๋ด์์ ์คํํ๋ ๋ชจ๋ ์ฐ๋ ๋์ ๋ํ ์ ๋ณด๋ฅผ ์ป์.
๊ฒฐ๊ณผ
Name : Signal Dispatcher(๋ฐ๋ชฌ)
์์๊ทธ๋ฃน : system
Name : AutoSaveThread(๋ฐ๋ชฌ)
์์๊ทธ๋ฃน : main
Name : main(์ฃผ)
์์๊ทธ๋ฃน : main
Name : Attach Listener(๋ฐ๋ชฌ)
์์๊ทธ๋ฃน : system
Name : Finalizer(๋ฐ๋ชฌ) - ๊ฐ๋น์ง ์ปฌ๋ ํฐ ๋ด๋น.
์์๊ทธ๋ฃน : system
Name : Reference Handler(๋ฐ๋ชฌ)
์์๊ทธ๋ฃน : system
์์ ์ฐ๋ ๋๋ ๋๋ถ๋ถ ๋ฉ์ธ์ฐ๋ ๋์์ ์์ฑํ๋ค. ์ฐ๋ ๋์ ๊ทธ๋ฃน์ ์ง์ ์ ํด์ฃผ์ง ์์ผ๋ฉด ๋ํด๋๋ก ํ์ฌ ์ฐ๋ ๋์ ๊ทธ๋ฃน์ ์ํ๊ฒ ๋๋ค. ๋ฐ๋ผ์ AutoSaveThread๋ ๋ฉ์ธ์ฐ๋ ๋์์ ์์ฑํ์์ผ๋ฏ๋ก ๋ฉ์ธ์ฐ๋ ๋์ ๊ทธ๋ฃน์ ์ํ๋ main๊ทธ๋ฃน์ ์ํ์๋ค.
ThreadGroup ํด๋์ค๊ฐ ๊ฐ์ง๊ณ ์๋ ์ฃผ์ ๋ฉ์๋
ย | ๋ฉ์๋ | ์ค๋ช |
---|---|---|
int | activeCount() | ํ์ฌ ๊ทธ๋ฃน ๋ฐ ํ์ ๊ทธ๋ฃน์์ ํ๋์ค์ธ ๋ชจ๋ ์ฐ๋ ๋์ ์๋ฅผ ๋ฆฌํดํ๋ค. |
int | activeGroupCount() | ํ์ฌ ๊ทธ๋ฃน์์ ํ๋ ์ค์ธ ๋ชจ๋ ํ์ ๊ทธ๋ฃน์ ์๋ฅผ ๋ฆฌํดํ๋ค |
void | checkAccess() | ํ์ฌ ์ฐ๋ ๋๊ฐ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ๋ณ๊ฒฝํ ๊ถํ์ด ์๋์ง ์ฒดํฌํ๋ค. ๋ง์ฝ ๊ถํ์ด ์์ผ๋ฉด SecurityException์ ๋ฐ์์ํจ๋ค |
void | destroy() | ํ์ฌ ๊ทธ๋ฃน ๋ฐ ํ์ ๊ทธ๋ฃน์ ๋ชจ๋ ์ญ์ ํ๋ค. ๋จ, ๊ทธ๋ฃน ๋ด์ ํฌํจ๋ ๋ชจ๋ ์ฐ๋ ๋๋ค์ด ์ข ๋ฃ ์ํ๊ฐ ๋์ด์ผ ํ๋ค. |
boolean | isDestroyed() | ํ์ฌ ๊ทธ๋ฃน์ด ์ญ์ ๋์๋์ง ์ฌ๋ถ๋ฅผ ๋ฆฌํดํ๋ค |
int | getMaxPriority() | ํ์ฌ ๊ทธ๋ฃน์ ํฌํจ๋ ์ฐ๋ ๋๊ฐ ๊ฐ์ง ์ ์๋ ์ต๋ ์ฐ์ ์์๋ฅผ ๋ฆฌํดํ๋ค |
void | setMaxPriority(int pri) | ํ์ฌ ๊ทธ๋ฃน์ ํฌํจ๋ ์ฐ๋ ๋๊ฐ ๊ฐ์ง ์ ์๋ ์ต๋ ์ฐ์ ์์๋ฅผ ์ค์ ํ๋ค |
String | getName() | ํ์ฌ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ์ด๋ฆ์ ๋ฆฌํดํ๋ค. |
ThreadGroup | getParent() | ํ์ฌ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ๋ถ๋ชจ๊ทธ๋ฃน์ ๋ฆฌํดํ๋ค. |
boolean | parentOf(ThreadGroup g) | ํ์ฌ ๊ทธ๋ฃน์ด ๋งค๊ฐ๊ฐ์ผ๋ก ์ง์ ํ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ๋ถ๋ชจ์ธ์ง ์ฌ๋ถ๋ฅผ ๋ฆฌํดํ๋ค. |
void | setDaemon(boolean daemon) | ํ์ฌ ๊ทธ๋ฃน์ ๋ฐ๋ชฌ๊ทธ๋ฃน์ผ๋ก ์ค์ ํ๋ค. |
void | list() | ํ์ฌ ๊ทธ๋ฃน์ ํฌํจ๋ ์ฐ๋ ๋์ ํ์ ๊ทธ๋ฃน์ ๋ํ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ๋ค. |
void | interrupt() | ํ์ฌ ๊ทธ๋ฃน์ ํฌํจ๋ ๋ชจ๋ ์ฐ๋ ๋๋ค์ interruptํ๋ค. |
์ฐ๋ ๋ ๊ทธ๋ฃน์ ์ผ๊ด์ ์ผ๋ก interrupit() ํธ์ถ
์ฐ๋ ๋ ๊ทธ๋ฃน์ ์ฌ์ฉํ๋ ์ด์
- ๊ทธ๋ฃน๋ด ํฌํจ๋ ๋ชจ๋ ์ฐ๋ ๋๋ค์ ์ผ๊ด interrupt() ์์ผ์ ์์ ํ๊ฒ ์ข ๋ฃํ ์ ์๋ค. ์ฌ๋ฌ๋ฒ ํ ๊ฑธ ํ๋ฒ์ ๊ฐ๋ฅํ๋ค๋ ๊ฒ. - ํ์ง๋ง ์ฐ๋ ๋ ๊ทธ๋ฃน์ interrupt() ๋ฉ์๋๋ ์์๋ ์ฐ๋ ๋์ interrupt() ๋ฉ์๋๋ฅผ ์คํ๋ง ํ ๋ฟ ๊ฐ๋ณ ์ฐ๋ ๋์ InterruptedException ์์ธ์ฒ๋ฆฌ๋ ํ์ง ์๋๋ค.
- ๊ฐ๋ณ ์ฐ๋ ๋์์ InterruptedException ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค.
- ์์
public class WorkThread extends Thread{
public WorkThread(ThreadGroup threadGroup, String threadName) {
super(threadGroup, threadName);
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(getName()+" interrupted");
break;
}
}
System.out.println(getName()+ " ์ข
๋ฃ๋จ");
}
}
public class Main{
public static void main(String[] args) {
ThreadGroup myGroup = new ThreadGroup("myGroup");
WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
workThreadA.start();
workThreadB.start();
System.out.println("[main ์ฐ๋ ๋ ๊ทธ๋ฃน์ list() ๋ฉ์๋ ์ถ๋ ฅ ๋ด์ฉ]");
ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); //ํ์ฌ์ฐ๋ ๋์ ๊ทธ๋ฃน
mainGroup.list();
System.out.println();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
System.out.println("[myGroup ์ฐ๋ ๋ ๊ทธ๋ฃน์ interrupted() ๋ฉ์๋ ํธ์ถ]");
myGroup.interrupt();
}
}
- WorkThread ํด๋์ค๋ฅผ ๋ณด๋ฉด catch๋ฌธ์ผ๋ก interrupt ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ค ๋ชจ์ต์ด๋ค. while๋ฌธ์ ๋๋ฉด์ ์์ธ๋ฅผ ๋ฐ์์ํค๋ฉด ํ์ถํ๋ค.
- list ๋ฉ์๋๋ ํ์ฌ ๊ทธ๋ฃน์ ์ด๋ฆ๊ณผ ์ต๋ ์ฐ์ ์์๋ฅผ ํค๋๋ก ์ถ๋ ฅํ๊ณ ๊ทธ์๋ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ํฌํจ๋ ์ฐ๋ ๋์ ํ์ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ๋ด์ฉ์ ๋ณด์ฌ์ค๋ค.
- ๋งจ ์๋์ชฝ์ myGroup.interrupt() ๋ฉ์๋๋ ์ฐ๋ ๋ ๊ทธ๋ฃน์ ํฌํจ๋ ๋ชจ๋ ์ฐ๋ ๋์ interrupt() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
- ์คํ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋ฉ์ธ์ฐ๋ ๋๊ฐ ์ข ๋ฃํ ๋ค ๋๊ฐ์ WorkThread ๊ฐ์ฒด ์ฐ๋ ๋๊ฐ ์ข ๋ฃํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
[main ์ฐ๋ ๋ ๊ทธ๋ฃน์ list() ๋ฉ์๋ ์ถ๋ ฅ ๋ด์ฉ]
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
java.lang.ThreadGroup[name=myGroup,maxpri=10]
Thread[workThreadA,5,myGroup]
Thread[workThreadB,5,myGroup]
[myGroup ์ฐ๋ ๋ ๊ทธ๋ฃน์ interrupted() ๋ฉ์๋ ํธ์ถ]
workThreadA interrupted
workThreadA ์ข
๋ฃ๋จ
workThreadB interrupted
workThreadB ์ข
๋ฃ๋จ
์ฐ๋ ๋ ํ ์์ , ๊ฐ๋ (Future ๊ฐ์ฒด, execute(), submit())
์ฐ๋ ๋ํ
- ๋ณ๋ ฌ์์ ์ฒ๋ฆฌ๊ฐ ๋ง์์ง๋ฉด ์ฐ๋ ๋ ๊ฐ์ ์ฆ๊ฐ -> ์ฐ๋ ๋ ์์ฑ ๋ฐ ์ค์ผ์ฅด๋ง์ CPU๊ฐ ๋ฐ๋น ์ ธ์ ๋ฉ๋ชจ๋ฆฌ ๋ง์ด ์ฌ์ฉ
- ๊ฒฐ๊ตญ ์ฑ๋ฅ์ ํ.
- ๊ฐ์์ค๋ฐ ๋ณ๋ ฌ ์์ ์ฒ๋ฆฌ๊ฐ ๋ง์์ง ๋ ์ฐ๋ ๋ํ์ ์ด์ฉ.
- ์ฐ๋ ๋๋ฅผ ์ ํ๋ ๊ฐ์๋งํผ ์ ํด๋๊ณ ์์ ํ(Queue)์ ๋ค์ด์ค๋ ์์ ๋ค์ ํ๋์ฉ ์ฐ๋ ๋๊ฐ ๋งก์์ ์ฒ๋ฆฌ.
- ์ฐ๋ ๋ํ ์์ฑ/์ฌ์ฉ์ ์ํด Executors ํด๋์ค์ ExecutorService ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณต.
- Executors์ ๋ค์ํ ์ ์ ๋ฉ์๋๋ก ExecutorService์ ๊ตฌํ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋๋ฐ ์ด๊ฒ์ด ๋ฐ๋ก ์ฐ๋ ๋ํ.
์ฐ๋ ๋ํ ์์ฑ
Executors ํด๋์ค
- newCachedThreadPool()
- newFixedThreadPool()
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorService executorService2 = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors();
); //cpu์ ์ฝ์ด์๋งํผ ์ต๋์ฐ๋ ๋ํ ์์ฑ
์ฐ๋ ๋ํ ์ข ๋ฃ
executorService.shutdown() - ๋จ์์๋ ์์ ์ ๋ง๋ฌด๋ฆฌํ๊ณ ์ฐ๋ ๋ํ ์ข ๋ฃ
executorService.shutdownNow() - ๋จ์์๋ ์์ ๊ณผ๋ ์๊ด์์ด ๊ฐ์ ๋ก ์ข ๋ฃ
์์ ์์ฑ๊ณผ ์ฒ๋ฆฌ์์ฒญ
์์ ์์ฑ
- ํ๋์ ์์ ์ Runnable or Callable ๊ตฌํ ํด๋์ค๋ก ํํํ๋ค.
- Runnable(๋ฌด)๊ณผ Callable(์ )์ ์ฐจ์ด๋ ๋ฆฌํด๊ฐ์ ์ ๋ฌด์ด๋ค.
Runnable task = new Runnable(){
@Override
public void run(){ /*์ฐ๋ ๋๊ฐ ์ฒ๋ฆฌํ ์์
๋ด์ฉ*/ }
}
Callable<T> taskc = new Callable<T>(){
@Override
public T call() throws Exception{
//์ฐ๋ ๋๊ฐ ์ฒ๋ฆฌํ ์์
๋ด์ฉ
return T;
}
}
์์ ์ฒ๋ฆฌ์์ฒญ
- ExecutorService์ ์์ ํ์ Runnable ํน์ Callable๊ฐ์ฒด๋ฅผ ๋ฃ๋ ํ์
- ์์ ์ฒ๋ฆฌ ์์ฒญ์ ์ํด submit()๊ณผ execute() ๋ฉ์๋๋ฅผ ์ ๊ณตํจ.
- execute() : Runnable์ ์์ ํ์ ์ ์ฅ
- submit() : Runnable ๋๋ Callable์ ์์ ํ์ ์ ์ฅ, Future ๊ฐ์ฒด๋ฅผ ๋ฆฌํด
- submit ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฐ๋ ๋์ ์์ฑ์ค๋ฒํค๋๋ฅผ ์ค์ด๋๋ฐ ์ข๋ค. ์๋ํ๋ฉด execute๋ฉ์๋๋ ์์ ์ฒ๋ฆฌ์ค ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ์ฐ๋ ์ฐ๋ ๋๋ฅผ ๋ฒ๋ฆฌ๊ณ ์๋ก์ด ์ฐ๋ ๋๋ฅผ ์์ฑํ๋ค. ํ์ง๋ง submit ๋ฉ์๋๋ ์ฐ๋ ์ฐ๋ ๋๋ฅผ ์ฌํ์ฉํ๋ค.
(์ด๋ ์ฐ๋ ๋์ด๋ฆ์ ํตํด ํ์ธํ ์ ์๋ค.)
public static void main(String[] args) throws Exception{
ExecutorService executorService = Executors.newFixedThreadPool(2); //์ต๋์ฐ๋ ๋ ๊ฐ์๊ฐ 2์ธ ์ฐ๋ ๋ํ ์์ฑ
for(int i =0; i<10; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
int poolSize = threadPoolExecutor.getPoolSize();
String threadName = Thread.currentThread().getName();
System.out.println("[์ด ์ฐ๋ ๋ ๊ฐ์ : "+poolSize+"] ์์
์ฐ๋ ๋ ์ด๋ฆ :"+threadName);
//์์ธ ๋ฐ์์ํด
int value = Integer.parseInt("์ผ");
}
};
//์ด ๋๊ฐ๋ฅผ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์คํํด๋ณด์ธ์.
//executorService.execute(runnable);
executorService.submit(runnable);
Thread.sleep(10);//์ฝ์ ์ถ๋ ฅ์๊ฐ์ ์ํด 0.01์ด ์ผ์์ ์ง
}
executorService.shutdown();
}