쓰레드를 이야기 하다 보면 병렬성과, 동시성이라는 용어가 자주 나옵니다. 이 말은 무엇을 의미할까요? 그 전에, 우리는 쓰레드의 상태를 이해할 필요가 있습니다. 오늘은 그에 대해서 간단하게 이야기 해 보도록 하겠습니다.

 

 


 

 먼저, w[i] = new worker(); 문을 봅시다. 그러면, Thread를 상속받은 worker 객체가 생성이 됩니다. 그러면 worker-x는 생성이 되고, 아직 start()가 호출이 되지 않았어요. 이를 new 상태라고 이야기 합니다.

 

 


 

 

그 다음에 우리는 start() 메소드를 호출했습니다. t.start()를 호출하면, Thread를 상속받은 worker 클래스 내부의 run 메소드가 호출이 될 겁니다. 그러면, 실행 대기 상태가 됩니다.

 

 

 즉, 스케쥴러에 의해서 선택이 될 수 있는 상태를 의미합니다. 이 친구들은 스케쥴러에 의해서 다시 실행 대기 상태로 돌아갈 수도 있어요. 그러면, 스케쥴러가 어떠한 알고리즘에 의해서, 다른 쓰레드를 선택할 거에요. 쉽게 이야기 하면, 대기 큐에 있는 Thread가 여러개 있고, 그 중에서 스케쥴러가 T'을 선택합니다. 그러면 T'이 Runnable에서 Run 상태가 됩니다.

 

 

 

 이것은 아래 코드로 확인할 수 있어요.

 

 

 저는 worker가 몇 번째로 생성이 되었는지를 생성자의 인자에 넣었습니다. run 함수는 아래와 같습니다.

 

 

 이것은 간단합니다. 루프를 돌면서 i가 1000만의 배수일 때에만 현재 실행하고 있는 쓰레드가 몇 번째로 생성이 되었는지를 출력하는 겁니다. 일단 제 컴퓨터는 2코어 4쓰레드인데요. 출력 결과를 보면 다음과 같습니다.

 

 

 1이 출력되고 나서, 약 10여번 이상 1이 출력되지 않았어요. 그 말인 즉슨, run 상태가 되었다고 하더라도, 스케쥴러가 run 상태에 있는 쓰레드를 실행 대기 상태로 보낼 수도 있다는 거에요. 그리고 다른 친구를 실행 상태에 올릴 거에요. 그러면 어떤 문제가 발생할까요?

 

 Thread 여러 개가 공유 객체에 접근을 할 때, 실행 순서가 뒤죽 박죽이기 때문에 문제가 발생할 수 있어요. 이는 임계 영역이랑 synchronized 키워드를 다룰 때 다시 이야기 하도록 하겠습니다.

 

 


 그런데, 1가지 상태가 더 있습니다. wait. 사실 이것도 block이랑 time wait랑 wait로 나눌 수 있어요. 이 셋의 차이도 나중에 언급하도록 하겠습니다.

 

 

 Run 상태에서, wait 상태로 갈 수 있는데요. sleep이나, wait 함수를 호출하면 일시 정지. 기다리는 상태가 됩니다. main 함수에서 join을 호출했을 때에도 마찬가지인데요.

 

 

 이것도 내부적으로 wait() 함수를 호출했었습니다. w[i]가 종료가 될 때 까지 기다리는 함수라고 이야기를 했었습니다. 그런데, wait 상태에서 다시 실행 대기 상태로 갈 수 있을까요? 네. notify() 계열 함수나, interrupt()가 그러한 역할을 합니다.

 

 혹은, 이러한 경우도 있습니다.

 

 

 synchronized(this)는 this 객체에 lock을 거는 겁니다. 그러면, this 객체에, lock을 획득한 쓰레드 말고는 접근을 하지 못합니다. 만약에 Thread-1이 먼저 획득을 했다면, 나머지 친구들은 T1이 13번째 줄을 끝낼 때 까지 코드를 수행하지 못하게 됩니다.

 

 

 Blocked 되었다는 겁니다. 이건 쓰레드가 my_Object로 선언된 this 객체를 물고 있어서 그래요.

 

 

 실제로, worker 클래스에는 my_Object의 참조형인 oo가 있는데요. main 함수로 돌아가 보면

 

 

 객체 하나를 공통으로 넘기고 있으니, 당연한 소리에요. 모든 쓰레드가 my_Object의 특정 객체를 물고 있고, m.foo() 안에서, 동기화 블록이 있는 구조입니다. 그렇기에, 하나가 lock을 걸어버리면 나머지 Thread가 실행하지 못하게 되어 버립니다. blocked 되었다고 보면 좋아요.

 

 

 run() 메소드가 끝나면 쓰레드는 종료 상태가 됩니다. 이를 terminated 되었다고 합니다.