JAVA

Thread

스물훈 2020. 4. 29. 12:22

Thread

- 프로세스 내에 만드는 것으로 작업 도중 다른 작업으로 제어권을 넘길 수 있도록 해주는 작업 단위.

- 단독으로는 실행할 수 없고 프로세스(Method) 내에서 생성해서 실행

- 일반 메서드 호출은 하나의 메서드의 수행이 완료될 때까지 다른 메서드의 수행을 할 수 없는 구조

   이러한 방식을 동기식(Synchronized)라고 함.

- 스레드는 하나의 작업이 진행 중인 동안에도 제어권을 다른 스레드로 옮겨서 처리가 가능함. 

   이러한 방식을 비동기식(asynchronized)라고 함.

 

1. 생성

1) java.lang.Thread

- Thread클래스로부터 상속받는 클래스를 만들어서 run 메서드 구현

- 클래스의 인스턴스를 생성해서 start()를 호출

- Thread클래스에는 run 메서드 외 여러 메소드 존재

 

2) java.lang.Runnable 인터페이스를 이용

- Runnable 인터페이스를 구현한 클래스를 만들어서 run메서드를 구현

- 클래스의 인스턴스를 생성

- Thread클래스의 인스턴스를 생성할 때 생성자의 매개변수로 만들어진 인스턴스를 대입

- Thread클래스의 인스턴스가 run을 호출

- Runnable 인터페이스에는 run 메서드만 존재

 

2. Java에서 상속이나 구현하는 방법

1) 상속이나 구현한 클래스를 만들고 인스턴스를 생성

2) 클래스를 만들지 않고 상속이나 구현한 인스턴스를 생성 - 익명 클래스

 

Thread 인스턴스에 Runnable 인터페이스 대입
객체 생성 없이 일회성

 

Thread 상태 6가지

- new: Thread가 생성되었지만 실행 준비 안됨.

- runnable: thread가 jvm에 의해 실행되고 있거나 실행준비되어 스케줄링을 기다리는 상태.

- waiting: 다른 thread가 notify(),notifyall()을 불러주기를 기다리고 있는 상태

- timed_waiting: Thread가 sleep(n)호출로 인해 n밀리초 동안 잠을 자고 있는 상태

- block: thread가 i/o 작업을 요청하면 jvm이 자동으로 이 thread를 block상태로 만듦

- terminated: thread가 종료된 상태

 

1) Thread상태는 jvm에 의해 기록되고 관리됨

2) run() 메서드가 종료되면 thread는 종료

3) 한번 종료된 thread는 다시 시작 불가

4) thread에서 다른 thread를 종료시킬 수 있음(interrupt)

 

Daemon Thread

- Deamon Thread가 아닌 스레드가 없으면 자동으로 종료되는 스레드

   (백그라운드에서 작업하다 다른 스레드가 종료되면 같이 종료)

- 백그라운드에서 대기하다 요청 발생 및 조건 상황이 맞으면 작업을 수행하는 스레드.

- 가비지 컬렉터나 메인 thread가 대표적인 데몬 스레드

- Thread 객체를 생성하고 setDaemon(true)로 설정.

- 응용프로그램의 자동 저장 기능이나 온라인 게임에서 자동으로 데이터를 전송하는 작업을 데몬 스레드로 작성

   *주기적으로 실행되어야 하는 작업 중 자동으로 종료되면 좋은 작업에 사용.

 

Thread Priority(우선순위)

- 스레드의 우선순위 설정 가능

- 우선순위를 설정하면 스레드의 시작 순서나 동작 횟수를 서로 다르게 설정할 수 있음.

- getPriority 메서드를 이용해서 우선순위를 정수로 리턴 받고, 

   setPriority 메서드로 우선순위를 설정할 수 있음.

- 우선순위가 높다고 반드시 먼저, 자주 수행되는 건 아님.

- setPriority 메서드의 매개변수는 정수형인데, 직접 정수를 설정하지 말고

   Thread.MAX_PRIORITY, NORMAL_PRIORITY, MIN_PRIORITY 등으로 설정. 

  *윈도우의 우선순위는 1~10, 리눅스는 1~7이기 때문.

 

Thread Group

- 여러 개의 스레드를 묶어주기 위해서 제공하는 클래스

- 리눅스에서 제대로 동작하지 않는 경우가 있어서 실제 사용은 잘하지 않음

- List를 이용해서 직접 묶어서 사용

 

스레드의 강제 종료

1) inturrupt: 다른 작업을 방해하는 것

- 우선순위가 높은 작업이 발생시킨 인터럽트만 전달됨.

2) 강제 종료

- 스레드의 실행 구문에서 InterruptedException이 발생하면 return하도록 코드를 작성

- 스레드 인스턴스가 interrupt()라는 메소드를 호출하도록 하면 됨.

 

3) 되도록이면 스레드를 만들때 InterruptedException이 발생하면 종료하도록 작성하는것이 좋음.

    스마트폰의 경우 InterruptedException이 발생하면 현상태 저장해놓는것이 좋음.

 

synchronized(동기화): 순서대로 처리.

asynchronized(비동기): 순서를 알 수 없다.(동시에 처리하는것처럼 보이게 함)

 

Mutual Exclusion(상호 배제)

- 하나의 스레드가 수정하고 있는 자원을 사용을 끝내기 전에 다른 스레드가 수정할 수 없도록

   하는 것

- Critical Section(임계 영역): 공유 자원을 사용하는 코드 영역

 

1) Synchronized method

- 메소드의 결과형 앞에 synchronized를 붙여주면 이 메소드는 수행하고 있는 도중에 다른 스레드에게

   제어권을 넘기지 않는다.

 

Semaphore

- 동시에 수행할 스레드의 개수를 설정할 수 있는 클래스

- ThreadPool: 여러개의 스레드를 미리 만들어두고 빌려서 사용할 수 있도록 해주는 스레드의 집합

- 데이터베이스나 웹서버에서 많이 사용

Semaphore 예제