자바와 C#의 스레드

메서드 하나를 따로 돌리려면 무엇이 필요할까?

스레드 만들기

run에 적고 start로 시작합니다

자바에서 동시에 실행되는 단위는 run 메서드입니다. Thread를 물려받은 클래스에 run을 적고, 그 객체의 start를 부르면 run이 새 스레드에서 실행됩니다.

스레드는 2편의 태스크입니다. 메서드는 객체에 딸린 함수이고, 물려받기는 상속을 말합니다.

스레드 다루기

스레드를 다루는 메서드

Thread 클래스에는 스레드의 실행을 다루는 메서드가 있습니다. 부르면 그 스레드의 상태가 그림처럼 바뀝니다.

준비는 프로세서를 기다리는 상태, 막힘은 사건을 기다리는 상태입니다(2편). 우선순위의 보통은 NORM_PRIORITY, 최고는 MAX_PRIORITY, 최저는 MIN_PRIORITY입니다.

경쟁 동기화

synchronized가 객체를 잠급니다

메서드 앞에 synchronized를 붙이면, 그 메서드가 실행되는 동안 같은 객체의 다른 synchronized 메서드는 실행되지 못합니다. 6편의 모니터와 같은 원리입니다.

객체는 데이터와 메서드를 묶은 덩어리입니다. 메서드의 한 부분만 잠그려면 synchronized (식) 뒤에 그 부분을 적는 synchronized 문을 씁니다.

협력 동기화

wait로 물러나고 notify로 깨웁니다

버퍼가 비었는데 들어온 소비자 스레드는 wait를 불러 대기 목록으로 물러납니다. 생산자가 값을 넣고 notify를 부르면 기다리던 스레드 하나가 깨어납니다.

이 wait는 4편 세마포어의 wait와 이름만 같습니다. wait와 notify는 모든 클래스의 뿌리인 Object에 있어 어느 객체에나 쓸 수 있습니다.

notifyAll

깨어나도 다시 확인합니다

notifyAll은 대기 목록의 스레드를 모두 깨웁니다. 깨어났을 때 조건이 여전히 맞지 않을 수 있으므로, wait는 반드시 반복문 안에서 불러 조건을 다시 확인합니다.

값은 하나인데 둘이 깨어났습니다. 코드는 뜻만 적은 예시입니다.

C# 스레드

C#은 어떤 메서드든 스레드로

C#의 스레드는 자바를 바탕으로 하지만 다릅니다. 가장 큰 차이는 어떤 메서드든 자기 스레드에서 실행할 수 있다는 점입니다. Thread 객체를 만든 뒤 Start를 불러야 실행이 시작됩니다.

메서드 A와 B는 예시 이름입니다.

C#의 동기화

잠그는 방법이 셋입니다

C#은 동기화 방법을 셋 둡니다. 정수를 늘리고 줄이는 일만 맞추면 될 때는 Interlocked, 한 구간을 통째로 잠글 때는 lock, 잠그고 푸는 때를 더 세밀하게 나눌 때는 Monitor를 씁니다.

임계 구역(critical section)은 한 번에 한 스레드만 들어갈 수 있는 코드 구간입니다. Monitor는 6편의 모니터를 클래스로 내놓은 것입니다.

다음 편

스레드를 만들지 않고 반복문을 통째로 나누는 길도 있습니다

9편반복문 하나를 여러 프로세서가 나눠 돌리면? 12강 목록