본문 바로가기
Back-End/Java

스레드(Thread)

by 달의 조각 2022. 7. 19.

 

스레드란?
싱글 스레드 vs. 멀티 스레드
스레드 생성 방법 두 가지
스레드 실행
스레드 동기화
스레드 상태 이해, 제어

 


 

 

스레드란?

 

 

프로세스: 실행 중인 애플리케이션 = 데이터 + 컴퓨터 자원 + 스레드
스레드: 데이터와 애플리케이션이 확보한 자원으로 코드 실행, 이 흐름

 

메인 스레드(Main thread)

싱글 스레드 프로세스: 메인 스레드만 가진다

 

멀티 스레드(Multi-Thread)

동시 작업 가능, 여러 코드를 각 스레드에 분배하여 동시에 실행시킬 수 있다!
다수의 클라이언트 요청을 처리하는 서버를 개발할 때 사용
ex) 메신저 애플리케이션: 메시지를 주고받으며 파일 업로드 가능

 

 

 

스레드의 생성과 실행

 

 

메인 외 별도의 작업 스레드를 활용한다? = 작업 스레드가 수행할 코드 작성, 생성, 실행 → run() 메서드

 

1. Runnable 인터페이스 구현 객체에서 run()을 구현하여 스레드를 생성, 실행

public class ThreadExample1 {
    public static void main(String[] args) {

        Runnable task1 = new ThreadTask1();
        Thread thread1 = new Thread(task1);

        thread1.start();
    }
}


class ThreadTask1 implements Runnable {
    public void run() {
    	//수행할 작업 내용
    }
}

 

2. Thread 클래스를 상속 받은 하위 클래스에서 run()을 구현하여 스레드를 생성, 실행

Thread 클래스를 직접 인스턴스화하지 않는다

public class ThreadExample2 {
    public static void main(String[] args) {

       Thread thread2 = new ThreadTask2();

       thread2.start();
    }
}

class ThreadTask2 extends Thread {
    public void run() {
    	//수행할 작업 내용
    }
}

 

Runnable 익명 구현 객체를 활용한 스레드 생성, 실행

클래스를 따로 정의하지 않아도 됨!

public class ThreadExample3 {
    public static void main(String[] args) {

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //수행할 작업 내용 1
            }
        });

        thread1.start();

        //수행할 작업 내용 2
    }
}

 

Thread 익명 하위 객체를 활용한 스레드 생성, 실행

package thread;

public class ThreadExample2_2 {
    public static void main(String[] args) {

        Thread thread2 = new Thread() {
            public void run() {
                //수행할 작업 내용 1
            }
        };

        thread2.start();

        //수행할 작업 내용 2
    }
}

 


 

스레드의 이름

Thread-n

 

스레드의_참조값.getName()
스레드의_참조값.setName()

Thread.currentThread().getName() //스레드 인스턴스의 주소값 얻기

 

 


 

스레드 동기화

 

 

🛑 멀티 스레드 프로세스: 두 스레드가 동일한 데이터를 공유하면 문제!

 

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

임계 영역: 오로지 하나의 스레드만 실행할 수 있는 코드 영역
락: 임계 영억을 포함하는 객체에 접근할 수 있는 권한

 

synchronized : 임계 영역 설정하기

1. 메서드 전체를 지정: 메서드 반환 타입 좌측에 두기

public synchronized boolean withdraw(int money) {
	...
}


2. 특정 영역 지정

public boolean withdraw(int money) {
	synchronized (this) { //() 영역이 포함된 객체 참조
		 ... //코드 작성
	}
		
	return false;
   }
}

 

 


 

스레드 상태와 실행 제어

 

start() //실행 대기 상태로 만든다

 

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

 

static void sleep(long milliSecond) //클래스 메서드: Thread.sleep(1000); 클래스로 호출한다!

 

♾️ interrupt(): 일시 정지 스레드 대기로 복귀

void interrupt() //sleep(), wait(), join()에 의해 정지된 스레드 복귀 → 호출하면 정지 풀리며 예외 발생
try { Thread.sleep(1000); } catch (Exception error) {} //interrupt() 사용 시 예외 처리 필요!

 

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

static void yield()
public void run() {
		while (true) {
				if (example) {
						...
				}
				else Thread.yield();
		}
}

 

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

아래와 같은 경우 실행 대기 상태로 복귀

1. 시간 경과
2. interrupt() 호출
3.join() 호출

sleep()과 유사하지만, sleep()은 static 메서드이고 join()은 인스턴스 메서드이다

void join()
void join(long milliSecond)

 

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

public synchronized void methodA() {
    System.out.println("ThreadA의 methodA Working");
    notify();
    try { wait(); } catch (Exception e) {}
}

'Back-End > Java' 카테고리의 다른 글

StringBuilder의 사용, String으로 변환  (0) 2022.08.13
StringifyJSON  (0) 2022.07.22
파일 입출력(I/O)  (0) 2022.07.18
스트림  (0) 2022.07.17
람다  (0) 2022.07.16

댓글