The A :

728x90
반응형

Today I Lean

스레드와 JVM

 

 

 

학습목표 및 개념정리

# 스레드 (Thread)

- 스레드가 무엇인지 설명할 수 있다.

- 싱글 스레드와 멀티 스레드의 차이를 설명할 수 있다.

- 스레드를 생성하는 두 가지 방법을 활용할 수 있다.

- 스레드를 실행하고 동기화 할 수 있다.

- 스레드의 상태를 이해하고 제어할 수 있다.

 

# 자바 가상 머신 (Java Virtual Machine)

- JVM이 무엇인지 알고, 메모리 구조를 개괄적으로 이해한다.

- 가비지 컬렉션이 무엇인지 이해한다.

 

 

 

 

 

배운 것

# 스레드 (Thread)

1. 스레드(Thread) 란?

- 프로세스(Process)와 스레드(Thread)

  •  프로세스 : 실행중인 애플리케이션, 애플리케이션을 실행하면 운영체제로부터 실행에 필요한 만큼의 메모리를 할당받아 프로세스가 됨 (데이터, 컴퓨터 자원, 스레드로 구성)

 → 스레드는 데이터와 애플리케이션이 확보한 자원을 활용하여 소스 코드를 실행함 (하나의 코드 실행 흐름)

 

 

- 메인 스레드 (Main Thread)

  • 자바 애플리케이션을 실행하면 가장 먼저 실행되는 메서드는 main메서드
  • 메인스레드가 main 메서드를 실행시킴
  • 메인스레드는 main 메서드의 코드를 처음부터 차례로 실행시키며, 코드의 끝을 만나거나 return문을 만나면 실행종료

 → 다른 스레드 없이 메인스레드만 가지고 있는 애플리케이션은 싱글스레드 프로세스 라고 함

 

 

- 멀티 스레드 (Multi - Thread)

  • 하나의 프로세스는 여러개의 스레드를 가질 수 있음 (멀티 스레드 프로세스)
  • 여러 스레드가 동시에 작업을 수행할 수 있음 (멀티 스레딩)
  • 멀티스레딩은 하나의 애플리케이션에서 멀티테스킹을 구현하는데 핵심역할을 함

 

 

 

 

2. 스레드의 생성과 실행

- 작업 스레드 생성과 실행

  • 메인 스레드 외의 별도의 작업스레드 활용 : 작업 스레드가 수행할 코드 작성, 작업 스레드를 생성 / 실행시키는 것
  • 자바에서는 스레드가 수행할 코드도 클래스 내부에 작성해야 함
  • run() 이라는 메서드 내에 스레드가 처리할 적업을 작성하도록 규정되어 있음
  • run() 메서드는 Runnable 인터페이스와 Thread 클래스에 정의 되어 있음

▪ Runnable 인터페이스를 구현한 객체에서 run()을 구현하여 스레드를 생성하고 실행하는 방법

package thread;

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

        // Runnable 인터페이스를 구현한 객체 생성
        Runnable task1 = new ThreadTask1();

        // Runnable 구현 객체를 인자로 전달하면서 Thread 클래스를 인스턴스화 하여 스레드 생성
        Thread thread1 = new Thread(task1);

        // 위의 두 줄을 아래와 같이 한 줄로 축약할 수 있음
        //Thread thread1 = new Thread(new ThreadTask1());

        // 작업 스레드를 실행시켜, run() 내부의 코드 처리
        thread1.start();

        // 반복문 추가
        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

// Runnable에는 run()이 정의되어 있기 때문에 반드시 구현해야 함
class ThreadTask1 implements Runnable {

    // run()메서드 바디에 스레드가 수행할 작업 내용 작성
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.print("#");
        }
    }
}

// 출력 결과
@@@@@@@@@@@@@@@@@@@@@################@@@@@@@@@####@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@####
@@@@@@@@@@@@@@@@@@@@@@@@############################################################################

 

▪ Thread 클래스를 상속받은 하위 클래스에서 run()을 구현하여 스레드를 생성하고 실행하는 방법

package thread;

public class ThreadExample2 {
    public static void main(String[] args) {
        ThreadTask2 thread2 = new ThreadTask2();

        thread2.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}


// Thread 클래스를 상속받는 클래스 작성
class ThreadTask2 extends Thread {

    // run()메서드 바디에 스레드가 수행할 작업 내용 작성
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.print("#");
        }
    }
}

//출력 결과
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###############################################@@@#######
####################################@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##########

 → 두가지 방법 모두 같은 결과를 냄

  • @는 main 메서드의 반복문에서 출력한 문자 : @ 는 메인 스레드에 의해 출력
  • #는 run() 메서드의 반복문에서 출력한 문자 : #는 작업 스레드에 의해 출력
  • @와 #가 섞여 있음 : 메인스레드와 작업스레드가 동시에 병렬로 실행되면서 각각 main과 run()메서드의 코드를 실행

 

 

- 익명 객체를 사용하여 스레드 생성하고 실행하기

클래스를 따로 정의하지 않고도 익명 객체를 활용하여 스레드를 생성하고 실행시킬 수 있음

 

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

package thread;

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

        // 익명 Runnable 구현 객체를 활용하여 스레드 생성
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.print("#");
                }
            }
        });

        thread1.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

 

 

 

3. 스레드의 이름

- 스레드 이름 조회

: 메인스레드 외에 추가로 생성한 스레드는 기본적으로 "Thread-n" 이라는 이름을 가짐

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

        Thread thread3 = new Thread(new Runnable() {
            public void run() {
                System.out.println("Get Thread Name");
            }
        });

        thread3.start();

        System.out.println("thread3.getName() = " + thread3.getName());
    }
}

// 출력 결과
Get Thread Name
thread3.getName() = Thread-0

Process finished with exit code 0

 → " 스레드참조값.getName() " 으로 스레드의 이름 조회 가능

 

 

- 스레드 이름 설정

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

        Thread thread4 = new Thread(new Runnable() {
            public void run() {
                System.out.println("Set And Get Thread Name");
            }
        });

        thread4.start();

        System.out.println("thread4.getName() = " + thread4.getName());

        thread4.setName("Code States");

        System.out.println("thread4.getName() = " + thread4.getName());
    }
}

// 출력 결과
Set And Get Thread Name
thread4.getName() = Thread-0
thread4.getName() = Code States

Process finished with exit code 0

 → " 스레드참조값.setName() " 으로 스레드의 이름 설정 가능

 

 

- 스레드 인스턴스의 주소값 얻기

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

        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        });

        thread1.start();
        System.out.println(Thread.currentThread().getName());
    }
}

// 출력 결과
main
Thread-0

Process finished with exit code 0

 → " System.out.println(Thread.currentThread().getName()); " 으로 스레드의 이름 조회 가능

 

 

 

4. 스레드의 동기화

- 스레드 동기화 란?

: 멀티 스레드 프로세스는 두 스레드가 같은 데이터를 공유하게 되면서 발생하는 문제를 해결하기 위한 방법

▪ try { Thread.sleep(1000); } catch (Exception error) {}

 : Thread.sleep(1000);

 → 스레드를 일시정지 시키는 메서드 (어떤 스레드가 일시정지되면 대기열에서 기다리던 다른 스레드가 실행됨

 → Thread.sleep()은 반드시 try-catch 문의 try 블록 내에 작성해야 함

 → 1000 == 1초

 

try{} catch(){}

 : 예외 처리에 사용되는 문법

 → try 블록 내의 코드를 실행하다가 예외 또는 에러가 발생했을 때 catch 블록 내의 내용을 실행

 

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

        Runnable threadTask3 = new ThreadTask3();
        Thread thread3_1 = new Thread(threadTask3);
        Thread thread3_2 = new Thread(threadTask3);

        thread3_1.setName("김코딩");
        thread3_2.setName("박자바");

        thread3_1.start();
        thread3_2.start();
    }
}

class Account {

    // 잔액을 나타내는 변수
    private int balance = 1000;

    public int getBalance() {
        return balance;
    }
		
    // 인출 성공 시 true, 실패 시 false 반환
    public boolean withdraw(int money) {

        // 인출 가능 여부 판단 : 잔액이 인출하고자 하는 금액보다 같거나 많아야 합니다.
        if (balance >= money) {

            // if문의 실행부에 진입하자마자 해당 스레드를 일시 정지 시키고, 
            // 다른 스레드에게 제어권을 강제로 넘깁니다.
            // 일부러 문제 상황을 발생시키기 위해 추가한 코드입니다.
            try { Thread.sleep(1000); } catch (Exception error) {}

            // 잔액에서 인출금을 깎아 새로운 잔액을 기록합니다.
            balance -= money;

            return true;
        }
        return false;
    }
}

class ThreadTask3 implements Runnable {
    Account account = new Account();

    public void run() {
        while (account.getBalance() > 0) {

            // 100 ~ 300원의 인출금을 랜덤으로 정합니다. 
            int money = (int)(Math.random() * 3 + 1) * 100;

            // withdraw를 실행시키는 동시에 인출 성공 여부를 변수에 할당합니다. 
            boolean denied = !account.withdraw(money);

            // 인출 결과 확인
            // 만약, withraw가 false를 리턴하였다면, 즉 인출에 실패했다면,
            // 해당 내역에 -> DENIED를 출력합니다. 
            System.out.println(String.format("Withdraw %d₩ By %s. Balance : %d %s",
                    money, Thread.currentThread().getName(), account.getBalance(), denied ? "-> DENIED" : "")
            );
        }
    }
}

 

 

5. 스레드의 상태와 실행 제어

- 작업 스레드 생성과 실행

 

 

 

 

 

 

 

# 자바 가상 머신 (Java Virtual Machine)

1. apt 명령어

- 패키지 설치
 : sudo apt install 설치할패키지

 

 

 

 


 

 

↓ 이전 글 ↓

 

[코드스테이츠] 05_04_TIL : I/O, 스트림 심화

Today I Lean I/O, 스트림 심화 스트림과 사랑에 빠질 것 같은 느낌..? 스트림이랑 람다가 좀 재밌다고 느껴진다. 지금까지 약 한달간 코딩을 배우면서 재밌다? 라고 느껴진건 이번이 처음인것 같다!

theflower01.tistory.com

 

↓ 코트스테이츠 부트캠프 관련 글 한번에 보기 ↓

 

'IT/코드스테이츠 부트캠프' 카테고리의 글 목록

Flower, Plant, Study

theflower01.tistory.com

728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading