[Java] 멀티쓰레드 프로그래밍

케이·2022년 10월 2일
0

JAVA

목록 보기
14/17
post-thumbnail

학습한 내용을 정리한 포스팅입니다. 참고 문헌 내용이 직역 되어 어색한 문장이 있을 수 있습니다. 틀린 내용이 있다면 지적해주시면 감사하겠습니다.🙇🏻‍♀️

Thread 클래스와 Runnable 인터페이스

쓰레드를 만들기 위해서는 Thread 클래스를 Extends 하거나 Runnable 인터페이스를 implements 한다.

일반적으로는 후자를 더 많이 사용한다. 후자가 객체지향 관점(재사용성, 코드의 일관성 유지 가능)에 부합하기 때문이다.

예시 1. Thread 클래스를 상속

class MyThread extends Thread {
		public void run() { // Thread 클래스의 run()을 오버라이딩
			//작업할 내용	
		}
}
  1. Runnable 인터페이스를 구현
class MyThread implements Runnable {
			public void run() { //Runnable 인터페이스의 run()을 구현
			//작업할 내용
		}
}

쓰레드의 상태

아래와 같이 쓰레드의 상태를 6가지로 나눠 볼 수 있다. 현재 쓰레드의 상태를 확인하고 싶다면 Thread.getState()메소드를 사용하면 된다.

A thread state. A thread can be in one of the following states:

  • [NEW]A thread that has not yet started is in this state.
  • [RUNNABLE]A thread executing in the Java virtual machine is in this state.
  • [BLOCKED]A thread that is blocked waiting for a monitor lock is in this state.
  • [WAITING]A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
  • [TIMED_WAITING]A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
  • [TERMINATED]A thread that has exited is in this state.

출처: 오라클 공식문서

  1. New: 쓰레드가 시작되지 않은 상태
  2. Runnable: JVM안에서 실행될 수 있는 상태
  3. Blocked: 동기화 블럭에 의해서 일시 정지 된 상태
  4. Waiting: 수행을 위해 기한 없이 기다리는 상태
  5. Timed_waiting: 특정(정해진) 시간동안 기다리는 상태
  6. Terminated: 쓰레드가 종료된 상태

https://media.geeksforgeeks.org/wp-content/uploads/threadLifeCycle.jpg


쓰레드의 우선순위

쓰레드는 우선순위를 두어 실행이 가능하다. 이 때 우선순위 값에 따라 쓰레드가 얻는 실행시간이 달라진다.

쓰레드가 가질 수 있는 우선순위의 범위는 1부터 10이며 숫자가 높을 수록 우선순위가 높다. main 메소드를 수행하는 쓰레드의 경우 우선순위가 5이므로 main 메소드 내에서 생성하는 쓰레드의 우선순위는 5가 된다.

하지만 우선순위를 정해놓더라도 어떤 OS에서 실행되는지, 싱글 코어인지 멀티 코어인지에 따라 결과값이 다를 수 있다.

우선순위를 지정할 땐 setPriority(int newPriority)메소드를 사용한다.


Main 쓰레드

프로그램을 실행하면 기본적으로 하나의 쓰레드를 생성하는데 이 때 이 쓰레드가 main 쓰레드를 호출해서 작업이 수행되도록 한다. (사실 우리가 항상 쓰고 있는..)

동기화

한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하도록 막는 것을 쓰레드의 동기화 라고 한다.

싱글 쓰레드 프로세스의 경우 동기화 문제가 발생할 이유가 없지만 멀티 쓰레드 프로세스의 경우 여러 쓰레드가 같은 프로세스 내의 자원을 공유해서 사용하기 때문에 서로의 작업에 영향을 주게 된다.

예를 들어서 쓰레드 A가 작업하던 중에 쓰레드 B에게 제어권이 넘어가고 쓰레드 A가 사용하던 공유 데이터를 쓰레드 B가 변경한다면..?

쓰레드 A가 다시 제어권을 갖고 작업을 했을 때 원래 예상했던 결과와 결과 값이 다를 수 있다.

이런 현상을 막기 위해서

  • Lock
  • Critical Section

이라는 개념을 두고 있다.

자바에서는 Synchronized를 이용한 동기화 및 java.util.concurrent.locks와 java.util.concorrent.atomic 패키지를 통해서 (JDK1.5부터) 다양한 방식으로 동기화를 구현 할 수 있다.

예시)

//메서드 전체를 Critical Section으로 지정
public synchronized void myExample(){
			//내용
}

//특정 부분만 Critical Section으로 지정
synchronized(객체 참조변수){
		//내용
}

데드락

두 쓰레드가 자원을 점유한 상태에서 서로 상대편이 점유한 자원을 사용하려고 기다리느라 진행이 멈춰있는 상태를 말한다.

https://media.geeksforgeeks.org/wp-content/uploads/22-2.png

참고

남궁성, 자바의 정석
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html
https://www.geeksforgeeks.org/lifecycle-and-states-of-a-thread-in-java/
https://www.geeksforgeeks.org/deadlock-in-java-multithreading/?ref=gcse

profile
삽질하며 깨닫고 배웁니다. (a.k.a 프로삽질러) + 이 구역의 회고왕

0개의 댓글