[Become a Java-Masta👚‍🏫 6죌찚] 멀티쓰레드 프로귞래밍, Enum

배뭉·2021년 9월 23음
0
post-thumbnail

🎯 목표

자바의 멀티쓰레드 프로귞래밍, Enum에 대핮 학습하Ʞ.

📌 학습할 것

멀티쓰레드 프로귞래밍

Enum


멀티쓰레드 프로귞래밍

뚌저 Process 와 Thread의 찚읎점을 읎핎하고 넘얎가알 할 필요가 있닀.

  • 프로섞슀(Process) : OS 낎에서 싀행쀑읞 프로귞랚

  • 쓰레드(Thread) : 프로섞슀 낎에서 싀제 작업읎 싀행되는 흐늄의 닚위

따띌서 프로섞슀는 하나 읎상의 쓰레드륌 가지고 있닀.


음반적윌로 한 프로귞랚(Process)은 하나의 쓰레드륌 가지고 있지만, 프로귞랚 환겜에 따띌 둘 읎상의 슀레드륌 동시에 싀행할 수 있닀. 읎러한 싀행 방식을 멀티쓰레드(multithread)띌고 한닀.

귌데 왜 멀티프로섞슀 프로귞래밍읎 아니띌 멀티쓰레드 프로귞래밍을 할까?

멀티프로섞슀와 멀티쓰레드는 양쪜 몚두 여러 흐늄읎 동시에 진행된닀는 공통점을 가지고 있닀.

하지만 멀티프로섞슀에서 각 프로섞슀는 독늜적윌로 싀행되며 각각 별개의 메몚늬륌 찚지하고 있는 것곌 달늬 멀티쓰레드는 프로섞슀 낎의 메몚늬륌 공유핎 사용할 수 있닀. 또한 프로섞슀 간의 전환에는 많은 비용읎 소몚되Ʞ 때묞에 속도와 비용 잡멎에서 쓰레드가 유늬하Ʞ 때묞읎닀.

java에서는 쓰레드륌 2가지 방식윌로 구현할 수 있닀.

  1. Thread 큎래슀륌 상속
  2. Runnable 읞터페읎슀륌 구현

Thread 큎래슀

Thread 큎래슀륌 상속받아 쓰레드륌 구현하멎, Thread 큎래슀 낎의 run 메소드륌 재정의(Override) 하멎 된닀.

public class ThreadByThread extends Thread {
    @Override
    public void run() {
        System.out.println("Run Thread By Thread");
    }
}
public class Main {
    public static void main(String[] args) {
        ThreadByThread thread =new ThreadByThread();
        thread.start();
    }
}

Thread 큎래슀륌 상속받은 객첎륌 생성하여 start 메소드륌 혞출핚윌로썚 쓰레드륌 생성할 수 있닀.


Runnable 읞터페읎슀

Runnable 읞터페읎슀륌 구현하여 쓰레드륌 구현하멎, run 메서드 안에 쓰레드가 할 윔드륌 작성핎죌멎 된닀.

public class ThreadByRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Run Thread By Runnable");
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new ThreadByRunnable());
        thread.start();
    }
}

여Ʞ서 Runnable 객첎는 Thread객첎륌 생성하여 Thread 생성자에 파띌믞터로 넘Ʞ얎 Thread 타입윌로 생성 후 start 메소드륌 혞출핚윌로썚 쓰레드륌 생성할 수 있닀.


쓰레드 상태

쓰레드 슀쌀쀄링: 쓰레드의 개수가 윔얎(CPU)의 수볎닀 많을 겜우, 쓰레드륌 ì–Žë–€ 순서에 의핎 concurrent하게 싀행할 것읞가륌 정하는 작업

20170126_214028

싀행 상태: 싀행 대Ʞ 상태에 있는 쓰레드 쀑에서 쓰레드 슀쌀쀄링윌로 선택된 쓰레드가 CPU륌 점유하고 run()메소드륌 싀행한 상태

쓰레드 상태륌 확읞할 수 있도록 핎죌는 getState() 메소드는 쓰레드 상태에 따륞 Thread.State ì—Žê±° 상수륌 늬턎한닀.

상태엎거 상수섀명
생성NEW슀레드 객첎가 생성된 상태. 아직 start() 혞출 전
대ꞰRUNNABLE싀행될 쀀비(슀쌀쀄러에 의핎 선택 받Ʞ 전)륌 마친 상태. start() 혞출 됚
정지WAITING닀륞 슀레드로부터 였는 읎벀튞륌 대Ʞ하는 상태
TIMED_WAITING죌얎진 시간 동안 대Ʞ하는 상태
BLOCKED사용하고자 하는 객첎의 lock읎 풀멮 때까지 대Ʞ하는 상태
종료TERNINATED싀행읎 ë‹€ 끝난 상태

NEW로 쓰레드 객첎륌 생성하고, start() 메소드륌 혞출하멎 곧바로 쓰레드가 싀행되는 것처럌 볎읎지만 사싀은 쀀비가 완료된 대Ʞ 상태읎닀.

싀행 대Ʞ 상태에 있는 쓰레드 쀑에서 쓰레드 슀쌀쀄링윌로 선택된 쓰레드만읎 싀행 상태가 되고, 싀행 상태의 쓰레드는 run() 메소드륌 몚두 싀행하Ʞ 전에 쓰레드 슀쌀쀄링에 의핎 닀시 싀행 대Ʞ 상태로 돌아갈 수 있닀(interrupt).

귞늬고 싀행 대Ʞ 상태에 있는 닀륞 쓰레드가 선택(scheduler dispatch)되는 방식윌로 쓰레드 슀쌀쀄링읎 읎룚얎 진닀.

아래 표는 쓰레드의 상태륌 조작할 수 있는 메소드읎닀.

메소드섀명
static void yield()현재 쓰레드가 프로섞서의 현재 사용을 양볎(yield) 할 의사가 있닀는 슀쌀쀄러에 대한 힌튞읎닀.
static void sleep(long millis)현재 싀행쀑읞 쓰레드가 지정된 밀늬 쎈 동안 음시적윌로 싀행 쀑지 되도록 한닀. 슉, TIMED_WAITING 상태로 만든닀.
void join(long millis)읎 쓰레드가 작업읎 완료 될 때까지 Ʞ닀늰닀.
void interrupt()읎 쓰레드의 interrupted 상태륌 true로 변겜한닀.

쓰레드 우선순위

쓰레드에 우선순위륌 부여핚윌로썚 핎당 쓰레드가 뚌저 끝 날 확률을 높여쀀닀.

하지만, 우선순위가 높닀고 í•Žì„œ 묎조걎 뚌저 끝나는 것은 아니닀.


java에서 쓰레드의 우선순위륌 섀정하는 방법은 setPriority(int weight) 메소드륌 통핎 섀정 할 수 있닀.

weight 파띌믞터는 숫자가 큎수록 우선순위가 높은것읎며, 섀정 범위는 1부터 10까지 우선순위륌 섀정할 수 있닀.

디폮튾 weight는 쀑간값읞 5가 섀정된닀.


Main 쓰레드

Main 쓰레드는 몚든 자바 애플늬쌀읎션의 시작점읎닀.

Main 쓰레드로 프로귞랚읎 시작되얎 싀행을 되고, 멀티 쓰레드는 싱Ꞁ 쓰레드읞 Main 쓰레드에서부터 파생되얎 생성된 쓰레드띌고 할 수 있닀.

ì°žê³ ë¡œ, 멀티 쓰레드 얎플늬쌀읎션에서는 Main 슀레드가 종료되더띌도 자식 슀레드가 종료되지 않윌멎 얎플늬쌀읎션읎 종료되지 않는닀.

public static void main(String[] args) { // 메읞 쓰레드 
      Thread thread = new Thread(new ThreadByRunnable());  // 멀티 쓰레드 생성
      thread.start();
}

동Ʞ화

멀티쓰레드 프로귞래밍에서 여러 쓰레드가 한 프로섞슀낎 자원을 공유하므로 한 쓰레드가 진행쀑읞 작업을 닀륞 쓰레드 쪜에서 사용, 변겜하는 음읎 발생할 수 있닀.

읎러한 묞제점을 í•Žê²° 하Ʞ위핎 하나의 쓰레드만 영역 낎의 윔드륌 수행하도록 하는 쓰레드 동Ʞ화륌한닀.

java에서 2가지 방식윌로 멀티쓰레드 프로귞래밍 동Ʞ화 할 수 있닀.

  1. synchronized 킀워드 사용
  2. java.lang.Object 큎래슀의 wait(), notify(), notifyAll() 메소드 사용

1. synchronized 킀워드 사용

synchronized 킀워드로 싀행 랔록읎나, 메소드륌 임계 구역윌로 만듀얎 동Ʞ화 시킬 수 있닀.

동Ʞ화 랔록

synchronized(쓰레드 객첎){
     // 동Ʞ화 시킬 윔드
}

동Ʞ화 메소드

public static synchronized void syncMethod(){
   		// 동Ʞ화 시킬 윔드
}

핎당 동Ʞ화 랔록읎나, 메소드는 하나의 쓰레드만읎 진입될 수 있닀.

java.lang.Object 큎래슀의 wait(), notify(), notifyAll() 메소드 사용

아래 표의 메소드듀은 임계 구역에서만 사용 가능하닀.

메소드섀명
wait()닀륞 슀레드가 notify()로 불러쀄 때까지 대Ʞ한닀.
notify()묎작위로 대Ʞ 쀑읞 슀레드륌 깚워 RUNNABLE 상태로 변겜, 2개 읎상의 슀레드가 대Ʞ 쀑읎띌도 였직 한 개의 슀레드만 깚워 RUNNABLE 상태로 변겜한닀.
notifyAll()대Ʞ 쀑읞 몚든 슀레드륌 깚우고 몚두 RUNNABLE 상태로 변겜한닀.

데드띜

데드띜은, 두 개 읎상의 쓰레드듀읎 각자 자원을 점유한 상태에서 서로 닀륞 쓰레드의 자원을 요구하며 몚두 묎한정 대Ʞ쀑읞 상태륌 말한닀.

슉, 쓰레드1읎 자원1을 점유하였고, 쓰레드2가 자원2륌 점유한 상태에서 쓰레드1읎 자원2륌 요청하는데 쓰레드2도 자원 1을 요청하여 서로 자원을 점유한 채 요청만 하며 양볎하지 않고 버티는 상황읎닀.

귞렇Ʞ 때묞에 yield()륌 사용하여 양볎륌 하Ʞ도 한닀.


Enum

enum 읎란 ꎀ렚읎 있는 "상수"의 집합을 정의하는 타입윌로 큎래슀의 특수한 형식읎닀.

자바5부터 enum 타입읎 도입되었고, 변수, 메소드, 생성자륌 추가하여 사용할 수 있닀.

enum 타입은 여러 특성듀읎 졎재한닀.

  1. java.lang.Enum 큎래슀(추상 큎래슀)륌 상속한 완전한 큎래슀읎므로 필드와 메소드륌 가질 수 있윌며, 귞러므로 닀륞 큎래슀륌 상속받을 수 없닀.
  2. public static final 타입윌로 공개되며 상수와 동음하게 명칭을 전부 대묞자로 정의한닀.
  3. 고정된 상수듀의 집합읎Ʞ 때묞에 런타임읎 아닌 컎파음타임에 몚든 값을 알고있얎알 하므로 생성자의 접귌지정자가 private로 동적윌로 값을 변겜하여 생성하멎 안된닀.
  4. singleton 팚턎읎 적용되얎 필드에 졎재하는 상수 하나당 하나의 읞슀턎슀가 된닀.
  5. 싱Ꞁ톀윌로 졎재하므로 객첎륌 equals() 메소드가 아닌 == 로 비교가 가능하닀.

enum 정의하는 방법

public enum CHICEKN {
    [public static final] BBQ("BBQ치킚"),  //CHICEKN.BBQ로 ì ‘ê·Œ
    [public static final] PURADAK("푞닀띜치킚"), // ;가 아닌 ,
    [public static final] GOOBNE("굜넀치킚"); // 낎부적윌로 new로 생성한 것곌 같닀.

    private final String name; // 필드륌 가질 수 있음

    [private] CHICEKN(String name) { // private 생략
        this.name = name;
    }

    public String getName() { // 메소드륌 가질 수 있음
        return name;
    }
}

enum읎 제공하는 메소드

enum 타입은 java.lang.Enum 큎래슀륌 상속하므로 핎당 큎래슀의 메소드륌 사용할 수 있는데,

대표적읞 메소드로는 values(), valueOf(), ordinal()읎 있닀.

메소드섀명
values()몚든 enum 요소듀을 enum 타입 ë°°ì—Žë¡œ 반환
valueOf()특정 묞자엎읎 enum 타입윌로 졎재하멎 반환(졎재하지 않윌멎 exception 발생)
ordinal()핎당 enum 요소의 index륌 반환

EnumSet

읎늄 귞대로 Set을 Ʞ반윌로 쉜고 빠륎게 enum 타입 요소듀을 닀룰수 있는 Ʞ능을 제공한닀.

enum은 싱Ꞁ턎 팚턎의 닚음 객첎임을 볎장 핚윌로 핎싱작업을 필요로 하지 ì•Šêž° 때묞에 EnumSet은 enum의 요소 갯수가 64개륌 넘지 않는닀멎, 낎부적윌로 long 데읎터형의 64비튞 필드륌 읎용하여 좋은 성능을 볎여쀀닀.

대표적읞 EnumSet의 메소드로는 .allOf(enum.class), EnumSet.of(enum1, enum2...), EnumSet.complementOf(enum of EnumSet), EnumSet.range(enum1, enum4) 가 있닀.

메소드섀명
.allOf(enum.class)enum 타입의 몚든 요소듀을 가젞였Ʞ
EnumSet.of(enum1, enum2...)특정 enum요소듀을 가젞였Ʞ
EnumSet.complementOf(enum of EnumSet)특정한 enum요소륌 제왞하고 가젞였Ʞ
EnumSet.range(enum1, enum4)범위로 요소듀 가젞였Ʞ
profile
SSAFY 6th -> SEC VD SW 👚‍💻🔥

0개의 댓Ꞁ