SECTION
article thumbnail
Published 2020. 6. 18. 23:25
[Java] Thread JAVA

- 스레드(Thread)

 

: 프로세스 내에서 실행되는 흐름의 단위(작업 단위)

 

: 메모리를 할당받아 실행 중인 프로그램을 프로세스라고 함

: 프로세스 내의 명령어 블록으로 시작점과 종료점을 가짐

: 실행 중에 멈출 수 있으며 동시에 수행 가능

 

: 병렬적으로 처리 여러 개의 루틴을 가질 수 있는 게 장점

 

 

1) JVM에 의해 하나의 프로세스가 발생하고 main() 안의 실행문들이 하나의 스레드임

2) main() 이외의 또 다른 스레드를 만들려면 Thread 상속 or Runnable 인터페이스를 구현해야 함

3) 다중 스레드 작업 시에는 각 스레드끼리 정보를 주고받을 수 있음


- 스레드 클래스(java.lang.Thread)

 

 

 

<Thread 생성자>

 Thread()

 

 Thread(String s)

 스레드 이름

 Thread(Runnable r)

 인터페이스 객체 

 Thread(Runnable r, String s)

 인터페이스 객체와 스레드 이름 

 

<Thread 메서드>

 static void sleep(long msec) 

 throws Interrupted Exception

  msec에 지정된 밀리초 동안 대기

 String getName()

 스레드의 이름을 s로 설정 

 void setName(String s)

 스레드의 이름을 s로 설정

 void start()

 스레드를 시작 run() 메서드 호출

 int getPriority()

 스레드의 우선순위를 반환 

 void setpriority(int p)

 스레드의 우선순위를 p값으로 

 boolean isAlive()

 스레드가 시작되었고 아직 끝나지 않았으면 true 끝났으면 false 반환 

 void join() throws InterruptedException

 스레드가 끝날 때까지 대기  

 void run()

 스레드가 실행할 부분 기술 (오버 라이딩 사용)

 void suspend()

 스레드가 일시정지 resume()에 의해 다시 시작할 수 있다. 

 void resume()

 일시 정지된 스레드를 다시 시작. 

 void yield()

 다른 스레드에게 실행 상태를 양보하고 자신은 준비 상태로 

 


- Thread 생명주기

 

 

 

1. Runnable (준비상태)

: 스레드가 실행되기 위한 준비단계

: CPU를 점유하고 있지 않으며 실행(Running 상태)을 하기 위해 대기하고 있는 상태

: 코딩 상에서 start( ) 메서드를 호출하면 run( ) 메서드에 설정된 스레드가 Runnable 상태로 진입한다. “Ready “ 상태라고도 합니다.

 

2. Running (실행상태)

: CPU를 점유하여 실행하고 있는 상태이며 run() 메서드는 JVM만이 호출 가능함.

: Runnable(준비상태)에 있는 여러 스레드 중 우선순위를 가진 스레드가 결정되면 JVM이 자동으로 run( ) 메서드를 호출하여 스레드가 Running 상태로 진입한다.

 

3. Dead (종료 상태)

: Running 상태에서 스레드가 모두 실행되고 난 후 완료 상태. ( Done 상태)

 

4. Blocked (지연 상태)

: CPU를 점유권을 상실한 상태.
: 후에 특정 메서드를 실행시켜 Runnable(준비상태)로 전환.

: wait( ) 메서드에 의해 Blocked 상태가 된 스레드는 notify( ) 메서드가 호출되면 Runnable 상태로 간다.

: sleep(시간) 메서드에 의해 Blocked 상태가 된 스레드는 지정된 시간이 지나면 Runnable 상태로 간다.

 

 


- 스레드 생성

 

: 자바에서 스레드를 생성하는 방법은 2가지가 있음

 

1) Runnable 인터페이스를 구현하는 방법

2) Thread 클래스를 상속받는 방법

 

: 두 방법 모두 스레드를 통해 작업 내용을 run() 메서드에 작성하면 됨

 

 

 

 

- Runnable 인터페이스 이용

 

: JDK 라이브러리 인터페이스고 run() 메서드만 정의되어 있음

class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

 

 

 

 

- Thread 클래스 이용

 

: Thread 클래스로부터 제공되는 run() 메서드 오버 라이딩해서 사용

 

 class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
PrimeThread p = new PrimeThread(143);
p.start();

 

 

: run() 메서드가 종료하면 스레드는 종료됨.

: 스레드를 계속 실행시키려면 run() 메서드를 무한루프 되어야 함.

: 한번 종료된 스레드는 다시 시작할 수 없음 -> 스레드 객체를 다시 생성해야 함.

: 한 스레드에서 다른 스레드를 강제 종료할 수 있음.

 


- Daemon Thread

 

: 동일한 프로세스 안에서 주 스레드의 작업을 돕는 보조적인 역할을 하는 스레드

: 다른 스레드를 서비스해주면서 다른 스레드가 모두 종료되면 자신도 종료됨

 

: 워드 프레 세서의 자동 저장, 미디어 플레이어의 동영상 및 음악 재생, GC 등에 사용됨

: 프로그램이 종료되는 것을 막지 않으며 GC나 메인 스레드가 데몬 스레드임

 

: 스레드를 생성하고 setDaemon(true)를 설정하면 됨

=> 주의할 점은 thread.start() 전에 호출되어야 한다

=> 만약 호출되기 전에 실행될 시 IllegalThreadStateException이 발생함

 

: 스레드가 시작하기 전에 설정해야 함

 

boolean isDaemon()  // 스레드가 데몬 스레드인지 확인한다. 데몬 스레드이면 true 반환한다.
void setDaemon(boolean on) 
// 스레드를 데몬 스레드 또는 사용자 스레드로 변경한다.
// (매개변수 on의 값을 true로 지정하면 데몬 스레드가 된다.)

 


 

- 스레드 우선순위(Priority)

 

: 자바에서 각 스레드는 우선순위(priority)에 관한 자신만의 필드를 가지고 있음

: 이러한 우선순위에 따라 특정 스레드가 더 많은 시간 동안 작업을 할 수 있도록 설정할 수 있음

 

static int MAX_PRIORITY 스레드가 가질 수 있는 최대 우선순위를 명시함. (10)
static int MIN_PRIORITY 스레드가 가질 수 있는 최소 우선순위를 명시함. (1)
static int NORM_PRIORITY 스레드가 생성될 때 가지는 기본 우선순위를 명시함. (5)

 

: getPriority()와 setPriority() 메서드를 통해 스레드의 우선순위를 반환하거나 변경할 수 있음

: 스레드의 우선순위가 가질 수 있는 범위는 1부터 10까지이며, 숫자가 높을수록 우선순위 또한 높아진다

 

: 하지만 스레드의 우선순위는 비례적인 절댓값이 아닌 어디까지나 상대적인 값

: 우선순위가 10인 스레드가 우선순위가 1인 스레드보다 10배 더 빨리 수행되는 것이 아님

: 단지 우선순위가 10인 스레드는 우선순위가 1인 스레드보다 좀 더 많이 실행 큐에 포함되어, 좀 더 많은 작업 시간을 할당받을 뿐이다

 

: 스레드의 우선순위는 해당 스레드를 생성한 스레드의 우선순위를 상속받게 됩니다.

 

: main() 스레드의 우선순위 값은 초기값이 5

 

- 스레드 우선순위는 변경 가능

- void setPriority(int priority)
- int getPriority()

 

- JVM의 스케쥴링 규칙

- 철저한 우선순위 기반

- 가장 높은 우선순위의 스레드가 우선적으로 스케쥴링

- 동일한 우선순위의 스레드는 돌아가면서 스케쥴링(라운드 로빈)

 


 

- 스레드 종료

: run() 메서드에 예외처리에 return을 넣어 스스로 종료

: 타 스레드에서 강제 종료 시 interrupt() 메서드를 호출하면 InterruptedException 발생

 


- 멀티 스레드(multi thread)

 

: 여러 개의 스레드가 동시에 수행되면서 공유할 수 있을 때 공유되는 부분은 상호 배타적으로 사용되어야 한다.

: 자신이 속한 프로세서의 메모리를 공유하므로 시스템 자원의 낭비가 적음

 

- Dead Lock 문제

: 멀티 스레드를 사용할 때 주의할 점 중의 하나로 프로그램에서 스레드를 잘못 만들면 프로그램의 수행이 이루어지지 않고 무한 수행하는 Dead Lock을 만들 수 있음

 

- 임계 영역(critical section)

: 공유 자원을 사용하는 코드 영역을 임계 영역이라 한다.

: 이 부분에서는 공유 자원을 동시에 수정할 수 없도록 상호 배타적으로 실행될 수 있도록 작성되어야 한다.

 

- 자바에서 상호 배제 문제를 해결하는 방법

: 자바는 한순간에 하나의 스레드만 실행할 수 있는 synchronized method 제공

: 한 스레드가 synchronized method를 수행 중이면 다른 스레드는 대기

 

- 처리방법

- 공유 자원에 접근하는 메서드의 앞에 synchronized 메서드로 지정

- 공유 자원을 사용하는 영역을 synchronized(객체명)의 블록으로 지정


스레드 그룹(thread group)

: 서로 관련이 있는 스레드를 하나의 그룹으로 묶어 다루기 위한 장치

: 폴더를 생성해서 관련된 파일들을 함께 넣어서 관리하는 것처럼 함

: 모든 스레드는 반드시 스레드 그룹에 포함되어 있어야 함

: 우리가 생성하는 모든 스레드 그룹은 main 스레드 그룹의 하위 스레드 그룹이 되며 스레드 그룹을 지정하지 않고 생성한 스레드는 자동적으로 main 스레드 그룹에 속하게 됨


참고 자료

 

https://devbox.tistory.com/entry/Java-%EC%93%B0%EB%A0%88%EB%93%9C%EC%9D%98-%EC%8B%A4%ED%96%89%EC%A0%9C%EC%96%B4?category=574549

https://raccoonjy.tistory.com/15

http://tcpschool.com/java/java_thread_multi

https://jdm.kr/blog/69

https://coding-factory.tistory.com/279

 


 

profile

SECTION

@SectionR0

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그