관련 이론 및 문법

(synchronized 참고)

http://kkikkodev.tistory.com/143


문제 의도

주어진 코드를 컴파일한 후 실행한 결과를 고르는 문제입니다.


답안

F


풀이 방법

주어진 소스코드를 살펴보면, Computation 클래스가 Thread 클래스를 상속하고 있습니다. 멤버 변수로는 int 형 변수 num, boolean 형 변수 isComplete, int 형 변수 result 가 있습니다. 메소드로는, int 형 num 을 매개변수로 받는 매개변수 생성자가 있고, synchronized 된 메소드인 run 과 getResult 메소드가 존재합니다. 즉, 이 2 메소드는 현재 객체에 동기화되어 있는 메소드이므로, 동시에 실행될 수 없는 메소드입니다.


main 메소드를 실행하면, 크기가 4 인 Computation 인스턴스를 담을 수 있는 배열을 생성하고, computations 인스턴스로 가리킵니다. 그 후에, for 문을 computations.length (4) 번 돌면서, 매개변수 생성자를 호출하여 생성한 Computation 객체를 (매개변수로 차례대로 0, 1, 2, 3 을 넘겨서) 배열에 순서대로 담고, 각 객체의 start 메소드를 호출합니다. 즉, 4 개의 Computation 객체의 start 메소드가 호출된 것입니다. 서로 다른 4 개의 Computation 객체의 멤버 변수인 num 은 각각 0, 1, 2, 3 순서대로 저장되어 있고, isComplete 와 result 는 동일하게 false 와 0 으로 초기화되어 있습니다. 각각 다른 thread 이므로 서로 run 메소드를 호출하는데 영향을 주지 않습니다. 그러면서 동시에 main thread 는 main 메소드의 밑의 for 문을 실행하려고 합니다. 이 for 문에서는 computations 배열에서 각 요소를 돌면서 각 요소 객체의 getResult 메소드를 호출하여 받은 결과값을 출력하고 있습니다. 하지만 getResult 메소드는 run 메소드가 끝나기 전까지는 호출될 수 없습니다. (이 두 메소드는 synchronized 메소드이므로)


먼저, 첫 번째 배열 요소인 computations[0] 의 run 메소드가 호출되면, result = num * 2; 문장을 통해서 result 를 0 * 2 = 0 으로 변경하고, isComplete = true; 문장을 통해서 isComplete 를 true 로 변경합니다. 그 다음 notify() 메소드 호출을 통해서 혹시라도 wait() 를 부르고 대기하고 있는 thread 가 있다면 임의대로 한 thread 를 깨웁니다. 하지만 현재 wait 를 호출한 thread 가 없으므로 다음으로 넘어갑니다. 이렇게 run 메소드가 종료되면, main thread 쪽에서 c.getResult() 를 호출합니다. 그러면 isComplete 는 true 이므로 while 문에 들어가지 않고 바로 return result (0) 을 실행하여 화면에 0 을 출력하게 됩니다. 두 번째 배열 요소도 마찬가지로 run 메소드가 먼저 호출되어, result 를 1 * 2 = 2 로 만들고, isComplete 를 true 로 만들고 종료합니다. 그 다음 main thread 에서 c.getResult() 를 호출하여 2 를 화면에 출력하게 됩니다. 세 번째, 네 번째 배열 요소도 이와 같은 방식으로 진행되어, 화면에 4 6 을 출력하게 됩니다.


결국 화면에는 0 2 4 6 을 출력하게 되고, 답안은 F 가 됩니다.


by kkikkodev 2016. 11. 12. 21:14