코이_CO2
LIVING IS DYING
코이_CO2
전체 방문자
오늘
어제
  • 분류 전체보기 (45)
    • TIL ⚓️ (4)
      • OT주차 (1)
      • 1주차_풀스택 미니 프로젝트 (0)
      • 1주차_언어 기초(Java) (0)
      • 2주차_프로그래밍 기초 (1)
      • 3주차_주특기 입문(Spring) (0)
      • 4주차_주특기 숙련(Spring) (2)
    • WIL ⚓️ (0)
      • OT주차 (0)
      • 1주차_언어 기초(Java) (0)
      • 2주차_프로그래밍 기초 (0)
      • 3주차_주특기 입문(Spring) (0)
      • 4주차_주특기 숙련(Spring) (0)
    • Java의 정석 📖 (4)
      • Chapter 1. 자바를 시작하기 전에 (3)
      • Chapter 2. 변수 (0)
      • Chapter 3. 연산자 (0)
      • Chapter 4. 조건문과 반복문 (1)
    • Programmers (7)
      • Lv. 1 (7)
    • 혼자 공부하는 자바 📖 (8)
      • Chapter 05 참조 타입 (0)
      • Chapter 06 클래스 (3)
      • Chapter 07 상속 (1)
      • Chapter 08 인터페이스 (1)
      • Chapter 09 중첩 클래스 & 인터페이스 (0)
      • Chapter 10 예외 처리 (1)
      • Chapter 12 스레드 (1)
    • Java (2)
    • Spring (1)
    • Python (2)
    • Mysql (4)
    • Machine Learning (6)
      • 추측 통계 (2)
    • Data Analysis (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 개발일지
  • Spring Security
  • 부트스트랩
  • PYTHON
  • spring
  • TIL/WIL
  • 하루기록
  • 자바
  • 코딩
  • DTO
  • 웹개발 종합반
  • 스프링
  • 혼자공부하는자바
  • java
  • HTML
  • 개발자
  • 배열
  • 주특기 심화주차
  • 프로그래머스
  • sql
  • programmers
  • 혼자 공부하는 자바
  • jwt
  • TIL
  • LV1
  • 파이썬
  • 스터디
  • 항해99
  • CRUD
  • 게시판 프로젝트

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
코이_CO2
혼자 공부하는 자바 📖/Chapter 12 스레드

Chapter 12-1. 멀티 스레드(1)

Chapter 12-1. 멀티 스레드(1)
혼자 공부하는 자바 📖/Chapter 12 스레드

Chapter 12-1. 멀티 스레드(1)

2022. 12. 23. 05:25

멀티 스레드

 

프로세스(process)

  • 실행중인 하나의 애플리케이션
  • 운영체제로부터 실행에 필요한 메모리를 할당받아 애플리케이션의 코드를 실행하는 것

 

스레드(thread)

  • 프로세스 내부에서의 코드 실행 흐름

 

멀티 프로세스(multi process)

하나의 애플리케이션은 멀티 프로세스를 만들기도 하는데,

예를 들어 메모장을 2개 열어 작성한다면 2개의 메모장 프로세스 즉, 멀티 프로세스가 생성된 것

멀티 태스킹(multi tasking)

비슷한 의미로, 두 가지 이상의 작업을 동시에 처리하는 걸 멀티 태스킹이라고 하는데

운영체제는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킨다

음악을 들으며 워드로 문서 작성하는 것을 예로 들 수 있다.

 

하지만, 멀티 태스킹과 멀티 프로세스는 완전히 같진 않은데

애플리케이션 중에는 한 프로세스 내에서 멀티 태스킹을 할 수 있는 것도 있기 때문

메신저를 예로 들 수 있는데 메신저는 채팅 기능을 제공하면서 동시에 파일 전송 기능을 수행하기도 한다

이처럼 하나의 프로세스가 두 가지 이상의 작업을 처리하게 하기 위해서는 멀티 스레드를 사용

 

 

스레드

  • 한 가지 작업을 실행하기 위해 순차적으로 실행할 코드를 실처럼 이어놓은 것

멀티 프로세스에서 각 프로세스는 서로 독립적이라

한 프로세스에서 오류가 발생해도 다른 프로세스에 영향을 미치지 않는데,

 

멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 각 스레드는 다른 스레드에 영향을 미친다

멀티 스레드의 다양한 쓰임

  • 대용량 데이터의 처리 시간을 줄이기 위해 데이터를 분할해서 병렬로 처리할 때
  • UI를 갖고 있는 애플리케이션에서 네트워크 통신을 하기 위해
  • 다수 클라이언트의 요청을 처리하는 서버를 개발할 때

 


 

메인 스레드

  • 자바의 모든 애플리케이션은 메인 스레드가 main() 메소드를 실행하며 시작
  • main() 메소드의 첫 코드부터 아래로 순차적 실행
  • main() 메소드의 마지막 코드를 실행하거나 return문을 만나면 실행 종료
  • 필요에 따라 작업 스레드들을 만들어 병렬로 코드를 실행 가능
    • 즉, 멀티 스레드를 생성해서 멀티 태스킹 수행
  • 싱글 스레드 애플리케이션
    • 메인 스레드 종료 시 프로세스 종료
  • 멀티 스레드 애플리케이션
    • 실행 중인 스레드가 하나라도 있을 시 종료되지 않음

 


 

작업 스레드 생성과 실행

멀티 스레드 애플리케이션을 개발하기 위해서

몇 개의 작업을 병렬로 실행할지 결정하고 각 작업별로 스레드를 생성해야 한다

  • 메인 작업 이외의 추가적인 병렬 작업의 수만큼 스레드 생성
  • 자바에서는 작업 스레드도 객체로 생성되기 때문에 클래스가 필요
    • java.lang.Thread 클래스를 직접 객체화하여 생성
    • Thread 클래스를 상속해 하위 클래스를 만들어 생성

 

Thread 클래스로부터 직접 생성

Runnable을 매개값으로 갖는 생성자를 호출

Thread thread = new Thread(Runnable target);

Runnable

  • 작업 스레드가 실행할 수 있는 코드를 갖고 있는 객체
  • 인터페이스 타입이라 구현 객체를 만들어 대입
  • run() 메소드가 정의되어 있음
  • 구현 클래스는 run()을 재정의해서 작업 스레드가 실행할 코드를 작성

 

Runnable은 실제 스레드가 아닌 작업 내용을 갖고 있는 객체이기 때문에

이를 매개값으로 해서 Thread 생성자를 호출해야 작업 스레드가 생성

// Runnable 구현 클래스
class Task implements Runnable {
	public void run() {
    	스레드가 실행할 코드;
    }
}
Runnable task = new Task();
Thread thread = new Thread(task);

Thread 생성자를 호출할 때 Runnable 익명 객체를 매개값으로 사용하면 코드 절약 가능

Thread thread = new Thread(new Runnable() {
	public void run() {
    	스레드가 실행할 코드;
    }
} );

작업 스레드를 생성했어도 즉시 실행되지 않고 start() 메소드를 호출해야 실행

start() 메소드가 호출되면 매개값으로 받은 Runnable의 run()메소드를 실행하며 작업 처리

thread.start();

 

메인 스레드는 동시에 두 가지 작업을 처리할 수 없기 때문에

동시에 출력하기 위해서는 두 작업 중 하나를 메인 스레드가 아닌 다른 스레드에서 실행시켜야 한다

 

* 0.5초 주기로 비프음을 발생시키면서 동시에 출력하는 작업

  • 메인 스레드만 이용한 경우
    • 비프음을 발생한 다음 출력을 시작(동시 X)
public class BeepPrintExample1{
    public static void main(String[] args){
        Toolkit toolkit = Toolkit.getDefaultToolkit(); // Toolkit 객체 얻기
        for (int i = 0; i < 5; i++) {
            toolkit.beep();  // 비프음 발생
            try {Thread.sleep(500);} catch (Exception e) {}  // 0.5초간 일시 정지
        }
        for (int i = 0; i < 5; i++) {
            System.out.println("띵");
            try {Thread.sleep(500);} catch (Exception e) {}  // 0.5초간 일시 정지
        }
    }
}
  • 메인 스레드 + 작업 스레드
    • 출력은 메인 스레드가, 비프음을 들려주는 것은 작업 스레드가 담당
    • 작업을 정의하는 Runnable 구현 클래스를 작성 후 메인 스레드에 적용
    • 동시 실행
    • Runnable을 익명 구현 객체로 대체할 수도 있다
// 비프음을 들려주는 작업 정의
public class BeepTask implements Runnable {
    @Override
    public void run() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        for(int i=0; i<5; i++) {
            toolkit.beep();
            try { Thread.sleep(500); } catch (Exception e) {}
        }
    }
}
// 메인 스레드와 작업 스레드 동시 실행
public class BeepPrintExample2 {
    public static void main(String[] args) {
        Runnable beepTask = new BeepTask();  // BeepTask 객체 생성
        Thread thread = new Thread(beepTask);  // 작업 스레드 생성
        thread.start();  // BeepTask 실행 및 for문 실행하여 동시 출력

        for(int i=0; i<5; i++) {
            System.out.println("띵");
            try { Thread.sleep(500); }
            catch (Exception e) {}
        }
    }
}

 


 

Thread 하위 클래스로부터 생성

작업 스레드가 실행할 작업을 Runnable로 만들지 않고 Thread의 하위 클래스로 작업 스레드를 정의

Thread 클래스를 상속한 후 run() 메소드 재정의

public class WorkerThread extends Thread {
	@Override
    public void run() {
    	스레드가 실행할 코드;
    }
}
Thread thread = new WorkerThread();

Thread 익명 객체로 작업 스레드 객체를 생성하면 코드 절약 가능

Thread thread = new Thread() {
	public void run() {
    	스레드가 실행할 코드;
    }
};

Runnable과 마찬가지로 작업 스레드 객체에서 start() 메소드를 호출,

작업 스레드는 자신의 run() 메소드를 실행

thread.start();

 

* 0.5초 주기로 비프음을 발생시키면서 동시에 출력하는 작업

  • 비프음을 들려주는 스레드
public class BeepThread extends Thread {
    @Override
    public void run() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        for (int i = 0; i < 5; i++) {
            toolkit.beep();
            try { Thread.sleep(500);} catch (Exception e) {}
        }
    }
}
  • 메인 스레드와 작업 스레드가 동시에 실행
public class BeepPrintExample4 {
    public static void main(String[] args) {
        Thread thread = new BeepThread();  // BeepThread 객체 생성
        thread.start();  // BeepThread의 run() 메소드 실행 및 for문 실행하여 동시 출력

        for (int i = 0; i < 5 ; i++) {
            System.out.println("띵");
            try { Thread.sleep(500);} catch(Exception e) {}
        }
    }
}

 


 

스레드의 이름

스레드는 자신의 이름을 갖고 있다

  • 디버깅할 때 어떤 스레드가 어떤 작업을 하는지 조사할 목적으로 가끔 사용

메인 스레드

  • 'main' 이라는 이름을 갖음

직접 생성한 스레드

  • 자동적으로 'Thread-n' 이라는 이름으로 설정
  • n은 스레드 번호
  • Thread-n 대신 다른 이름으로 설정을 희망 시
    • Thread 클래스의 setName() 메소드로 변경
thread.setName("스레드 이름");

 

  • 스레드의 이름을 알고 싶은 경우
    • Thread 클래스의 getName() 메소드 호출
thread.getName();

 

스레드 객체의 참조

  • 인스턴스 메소드
    • 스레드 객체의 참조가 필요
    • setName(), getName()은 Thread 클래스의 인스턴스 메소드에 해당
  • 스레드 객체의 참조를 갖고 있지 않은 경우
    • Thread 클래스의 정적 메소드인 currentThread() 이용
    • 현재 스레드의 참조를 얻을 수 있음
Thread thread = Thread.currnetThread();
  • 멀티 스레드
  •  
  • 스레드
  •  
  • 메인 스레드
  •  
  • 작업 스레드 생성과 실행
코이_CO2
코이_CO2
나에게 찾아오는 뻔한 매일을 언제나 값지게 여길 줄 아는 내가 되기를

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.