이전 걸음에서 쓰레드의 임계영역에 대해서 같이 공부를 했습니다. 동기화에 대한 개념을 계속적으로 하고 있고 이번 걸음 또한 이전 걸음 임계영역과 더불어 쓰레드간 동기화를 할 수 있는 다른 방법을 이번 걸음에서 같이 보도록 하겠습니다.
쓰레드 통신을 이번 걸음에서 같이 공부를 해보도록 하겠습니다. 쓰레드와 쓰레드를 통신으로 연결을 함으로써 서로 동기화가 되도록 움직임을 구현을 할 수 있습니다. 쓰레드 통신이 무엇이고 동작 원리는 어떻게 되는지 같이 공부를 해보겠습니다.
쓰레드 통신이란 무엇인지, 사용 방법과 코드 예제를 통해서 쓰레드 통신을 자세히 알아보도록 하겠습니다. 쓰레드 통신이 이해가 가장 힘들 수 있지만 이 글을 끝까지 읽고 계속 보신다면 분명히 이해를 하고 사용을 하실 수 있다고 생각합니다.
쓰레드 통신 이란?
위의 사진처럼 wait(), notify(), notifyAll()이라는 메소드를 통해서 쓰레드가 통신을 할 수가 있습니다. wait를 통해서 기다리고 있습니다. 그럼 다른 쓰레드에서 동작을 마치고 나면 notify 또는 notifyAll을 통해서 wait하고 있는 쓰레드를 깨워주게 됩니다. 깨어난 쓰레드는 본인이 동작을 하고 notify 또는 notifyAll을 호출한 쓰레드는 스스로 wait를 함으로써 기다리게 합니다. 이렇게 작업을 하는 쓰레드와 기다리는 쓰레도 구분을 하고 통신을 해서 동작하고 기다리는 쓰레드로 나누게 되어서 동기화를 하게 합니다.
※ notify는 특정 하나의 쓰레드만 깨우고 notifyAll는 기다리는 모든 쓰레드를 깨웁니다.
쓰레드 통신 예제
class Factory{
private int value;
private boolean check = false;
synchronized void send(int value) {
while(check == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.value = value;
System.out.println("만드는 사람 : 만든다"+this.value);
notify();
check = true;
}
synchronized int get() {
while(check == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("사는 사람 : 산다"+this.value);
notify();
check = false;
return this.value;
}
}
class P extends Thread{
Factory f;
P(Factory f){
this.f = f;
}
public void run() {
for(int i = 0;i<10;i++) {
f.send(i);
}
}
}
class C extends Thread{
Factory f;
C(Factory f){
this.f = f;
}
public void run() {
int temp = 0;
for(int i = 0;i<10;i++) {
temp = f.get();
}
}
}
public class ThreadEx {
public static void main(String[] args) {
// TODO Auto-generated method stub
Factory f = new Factory();
P p = new P(f);
C c = new C(f);
p.start();
c.start();
}
}
위 소스를 보면 동기화가 맞춰서 만든다 산다가 출력이 되는 것을 확인을 할 수 있습니다. Factory class를 보면 synchronized 메소드가 2개가 있고 각각 P와 C클래스에서 호출을 하게 하고 있습니다. 이때 한 먼저 send 메소드가 실행이 되고 get메소드는 wait를 하게 됩니다. send의 할 일이 모두 끝나게 되면 notify로 get메소드를 깨우고 본인은 wait로 들어가게 됩니다. 서로 wait와 notify를 함으로써 통신을 하게 되고 결국에는 동기화가 되어서 일정한 값이 출력이 되는 것을 확인을 할 수 있습니다.