개발 일지/Java

[Java] 스레드(thread)

미숫가루설탕많이 2023. 1. 10. 10:46

 어떤 애플리케이션이 실행되면 운영체제가 해당 애플리케이션에게 메모리를 할당해주며 애플리케이션이 실행되는데, 이렇게 실행 중인 애플레케이션을 '프로세스'라고 한다. 그리고 프로세스 내에서 실행되는 소스 코드의 실행 흐름을 '스레드'라고 한다. 스레드는 데이터와 애플리케이션이 확보한 자원을 활용하여 소스 코드를 실행한다.

 

 즉, 스레드(thread)란 프로세스(process) 내에서 실제로 작업을 수행하는 주체를 의미한다. 모든 프로세스에는 한 개 이상의 스레드가 존재한다.

 

 

 

 

메인 스레드(Maint thread)

 자바 애플리케이션을 실행하면 가장 먼저 실행되는 메서드는 main 메서드이며, 메인 스레드가 main 메서드를 실행시켜준다. 메인 스레드는 main 메서드의 코드를 처음부터 끝까지 순차적으로 실행시키며, 코드가 끝나거나 return문을 만나면 실행을 종료한다.

 

 어떤 자바 애플리케이션의 소스 코드가 싱글 스레드로 작성되었으면, 프로세스가 될 때 오로지 메인 스레드만 가지는 싱글 스레드 프로세스가 된다. 반면, 메인 스레드에서 또 다른 스레드를 생성하고 실행시킨다면 해당 애플리케이션은 멀티 스레드로 동작한다.

 

 

 

 

멀티 스레드(Multi-thread)

 두 개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스라고 한다. 즉, 하나의 프로세스가 여러 개의 스레드를 가질 수 있으며 여러 스레드가 동시에 작업을 수행할 수 있다.

 

 

 

 

스레드의 생성과 실행


 자바는 객체지향 언어이기 때문에 스레드가 수행할 코드를 클래스 내부에 작성해줘야 하며, run() 이라는 메서드 내에 스레드가 처리할 작업을 작성해야 한다.

 

 run() 메서드는 Runnable 인터페이스와 Thread 클래스에 정의되어져 있다. 따라서, 작업 스레드를 생성하고 실행하는 방법은 다음과 같이 두 가지가 있다. 두 방법 모두 스레드를 통해 작업하고 싶은 내용을 run() 메서드에 작성하면 된다.

 

  1. Runnable 인터페이스를 구현하는 방법
  2. Thread 클래스를 상속받는 방법

 

 Runnable 인터페이스는 run() 메서드 단 하나만을 갖는 간단한 인터페이스이며, Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없다. 따라서, 일반적으로 Runnable 인터페이스를 구현하는 방법으로 스레드를 생성한다.

 

 

 

 

스레드의 동기화


 싱글 스레드 프로세스의 경우 프로세스 내에서 단 하나의 스레드만 작업하기 때문에 문제가 없지만, 멀티 스레드 프로세스의 경우 여러 스레드가 같은 프로세스 내의 자원을 공유해서 작업하기 때문에 서로의 작업에 영향을 준다.

 

 이러한 상황이 발생하지 않게 하는 것을 '스레드의 동기화'라고 한다.

 

 두 스레드가 동시에 실행하지 못하게 하려면 withdraw() 메서드를 사용하면 된다.

 

 withdraw() 메서드를 임계 영역으로 설정해야 하는데, 특정 코드 구간을 임계 영역으로 설정할 때는 synchronized 키워드를 사용한다. 다음은 synchronized 키워드를 사용하는 두 가지 방법이다.

 

  1. 메서드 전체를 임계 영역으로 지정하기
    : withdraw()의 반환타입 앞에 synchronized를 붙여준다.

  2. 특정 영역을 임계 영역으로 지정하기

 

 

 

 

임계 영역(Critical section)과 락(Lock)

 '임계 영역'은 오로지 하나의 스레드만 코드를 실행할 수 있는 코드 영역을 의미하고 '락'은 임계 영역을 포함하고 있는 객체에 접근할 수 있는 권한을 의미한다.

 

 만약 임계 영역으로 설정된 객체가 다른 스레드에 의해 작업이 이루어지고 있지 않을 때, 임의의 스레드 A는 해당 객체에 대한 락을 획득하여 임계 영역 내의 코드를 실행할 수 있다. 이 때, 다른 스레드들은 락이 없으므로 이 객체의 임계 영역 내의 코드를 실행할 수 없다.

 

 스레드 A가 코드를 모두 실행하면 락을 반납하고 다른 스레드들 중 하나가 락을 획득하여 다시 임계 영역 내의 코드를 실행한다.

 

 

 

 

스레드 실행 제어 메서드


  • sleep(long milliSecond)
    : milliSecond 동안 스레드를 잠시 멈춤

  • interrupt()
    : 일시 중지 상태인 스레드를 실행 대기 상태로 복귀

  • yield()
    : 다른 스레드에게 실행 양보

  • join()
    : 다른 스레드의 작업이 끝날 때까지 대기

  • wait(), notify()
    : 스레드 간 협업에 사용

'개발 일지 > Java' 카테고리의 다른 글

[Java] JDBC  (0) 2023.02.20
[Java] 자바 가상머신(JVM)  (0) 2023.01.10
[Java] 스트림(Stream)  (0) 2023.01.06
[Java] 람다식(Lambda Expression)  (0) 2023.01.06
[Java] 애너테이션(Annotation)  (0) 2023.01.06