유데미 X 웅진 STARTERS 취업 부트캠프 백엔드 3기 - 5주차 학습 일지_Thread

zwundzwzig·2022년 12월 25일
0
post-thumbnail

일전에 자바스크립트는 싱글 스레드 기반 언어임을 공부했다.

스레드는 프로세스 내에서 Code, Data, Heap 영역을 공유하면서 작업에 필요한 독립적인 메모리 공간인 Stack에 변수, 함수 호출 시 전달되는 인자, 작업 후 되돌아갈 주소값 등을 저장한다.

싱글 스레드 언어인 자바스크립트와는 다르게, 자바는 멀티 스레드를 활용해 기존에 생성된 프로세스의 리소스를 효율적으로 활용할 수 있다.

Thread vs Runnable

자바에서 스레드를 구현하는 방법은 Thread 클래스를 상속받거나 Runnable 인터페이스를 구현하는 두 가지 방법이 존재한다.

Thread_first t1 = new Thread_first();
// Thread_first extends Thread;
Runnable r = new Thread_second();
Thread t2 = new Thread(r);
// Thread_second implements Runnable
// 위 두 코드 줄여서 밑에 한 줄로 표현 가능.
Thread t2 = new Thread(new Thread_second());

두 방법 모두 run() 메소드를 갖고 있다.

그래서 스레드 클래스를 상속 받은 클래스가 run 메소드를 오버라이딩하거나, 런어블 인터페이스를 구현하는 클래스가 추상 메소드인 run을 구현하는 것으로 스레드를 구현할 수 있다.

재사용성이 높고 코드의 일관성을 유지할 수 있는 Runnable 인터페이스를 구현하는 게 더욱 객체지향적인 방법이라고 책에서 설명하고 있다.

또한, 두 방법 모두 start() 메소드를 호출할 수 있다.

여기서 run이 호출되면 자신의 스택에서 (아마 main 스택일 것.) 인스턴스를 구현하는 것인 반면,
start가 호출되면 아예 새로운 스택을 생성해 OS 스케줄러에 의해 main 스택과 번갈아 실행된다.

MultiThread

앞서 start 메소드로 새로운 스레드를 생성해 멀티스레딩을 할 수 있다고 상술했다.

참고로 스레드를 공부하며 여기서 자바의 몇 안 되는 OS 종속적인 부분이 나타나는데, 멀티스레딩이 적용된 프로세스가 JVM이 아닌, OS의 프로세스 스케줄러의 영향을 받기 때문이다.

그래서 상황에 따라 불규칙하게 스레드에 시간이 할당돼 개발자가 원치 않는 답을 얻을 수도 있다.

그럼에도 자바는 멀티스레드를 사용하기 때문에 사용자로부터 데이터를 입력 받거나 네트워크로 파일을 주고 받는 등의 서로 다른 자원을 활용하는 작업에서 속도적인 강점을 보인다.

그리고 스레드 멤버인 void setPriority(int newPriority) 메서드를 활용해 1부터 10 사이에 인자를 넣어 인스턴스마다의 우선 순위를 지정해줄 수 있다.

스레드의 상태 및 실행 제어

스레드는 총 다섯 가지 상태로 표현된다.

statementsexplain
new스레드가 생성 후 start 메소드로 호출되지 않은 상태
runnable실행 가능한 상태
running실행 중인 상태
blocked / waiting동기화나 다른 메소드로 인해 일시정지된 상태
terminated / dead작업이 종료된 상태

그리고 스레드의 실행을 제어하는 몇 가지 메소드에 대해서도 알아보자. ?가 앞에 붙으면 생략 가능한 매개변수

methodexplain
static void sleep(long milis, ?int nanos)일정 시간동안 스레드를 정지시킨다. 자바스크립트의 setTime~ 메소드들과 비슷하다.
void join(?long milis, ?int nanos)자신이 하던 일을 멈추고 다른 스레드가 지정된 시간동안 작업하는 것을 기다린다. 자바스크립트의 async-awiat 구문과 비슷하다고 느꼈다.
void interrupt()위 두 메소드로 정지상태의 스레드를 깨워 runable 상태로 만든다.
void stop()스레드 즉시 종료.
static void yield()실행 중 주어진 시간을 다른 스레드에 양보하고 대기 상태로 변환된다.

스레드의 동기화

싱글 스레드와 달리 멀티스레드는 한 프로세스의 리소스를 공유하기 때문에 각각의 스레드 간 서로의 영역을 방해하지 않도록 관리해줘야 한다.

공유 데이터를 사용하는 코드 영역을 임계 영역 critical section으로 지정하고, 각각의 객체가 갖고 있는 락 lock을 획득한 스레드만 이 영역 내 코드를 수행하도록 하는 방식이며 이러한 방식을 스레드의 동기화라고 한다.

자바는 원래 synchronized 키워드를 활용해 동기화를 지원했다. 하지만 이 방법은 지정된 영역의 코드를 한 번에 하나의 스레드만 수행하도록 하기 때문에 전체적으로 시간적 효율성 문제가 제기됐다.

JDK1.5부터, 여러 패키지에서 다양한 메소드를 제공하기 때문에 더욱 편리하게 동기화를 사용할 수 있게 됐다.

예전 상속을 공부할 때, Object 클래스 중 wait, notify, notifyAll 메소드를 공부했다.

wait -> 스레드가 락을 반납하고 작업을 중단한다.
notify -> 스레드가 락을 얻어 작업을 진행한다.
notifyAll -> 어차피 락은 하나의 스레드밖에 얻지 못하기 때문에 notify와 큰 차이가 없지만, starvation & race condition 개념에서 사용된다.

이외에도 Lock, Condition, volatile, fork & join 등의 개념이 책에 나와 있지만, 해당 개념은 좀 더 숙지 후 기재하도록 하자.


본 후기는 유데미 X 웅진씽크빅 취업 부트캠프 3기 백엔드 과정 학습 일지 리뷰로 작성되었습니다.

유데미 바로가기 / STARTERS 취업 부트캠프 공식 블로그 보러가기


🧷 참고 교재

  • [도우출판]Java의 정석 3rd Edition, - 남궁성
profile
개발이란?

0개의 댓글