[TIL#7] Java 문법 종합반 5주차

Jiwoo·2024년 4월 29일
0

내일배움캠프

목록 보기
11/65
post-thumbnail

학습 내용


쓰레드

📌 프로세스

  • 실행 중인 프로그램

  • 구조

    • Code
    • Data: 전역 변수, 정적 변수, 배열 등 초기화된 데이터의 저장 공간
    • Memory
      • Stack: 지역변수, 매개변수 리턴 변수 저장
      • Heap: 동적으로 필요한 변수 (new(), malloc())

📌 쓰레드

  • 프로세스 내에서 일하는 일꾼(코드 실행의 흐름)

  • 여러 쓰레드들이 있고 실행을 위한 프로세스 내 주소 공간이나 메모리 공간(Heap) 공유 받는다

  • 각가 명령 처리를 위한 자신만의 메모리 공간(Stack)도 할당 받는다

📌 싱글 쓰레드

  • 프로세스 안에서 하나의 쓰레드만 실행되는 것

  • Java에서 main() 메서드만 실행시켰을 때

  • JVM의 메인 쓰레드 종료되면, JVM도 같이 종료

📌 멀티 쓰레드

  • 프로세스 안에서 여러 개의 쓰레드 실행되는 것(프로세스의 자원 공유)

  • 여러 개의 작업 동시에 할 수 있어 성능 좋아진다

  • 스택을 제외한 모든 영역에서 메모리를 공유해 자원 효율적 사용

  • 동기화 문제 발생 → 자원 서로 사용하려다 충돌

  • 교착 상태(데드락) 발생 → 서로의 자원 원하는 상태일 때 서로의 작업 종료만 기다리며 진행 못함


Thread와 Runnable

📌 Thread

  • Thread 클래스 상속받음 (Java 제공)
public class TestThread extends Thread {
		@Override
		public void run() {
			 // 쓰레드 수행작업
		}
}

...

TestThread thread = new TestThread(); // 쓰레드 생성
thread.start() // 쓰레드 실행
  • run() 메서드에 작성된 코드가 쓰레드가 수행할 작업

📌 Runnable

  • Runnable 인터페이스 사용
public class TestRunnable implements Runnable {
		@Override
		public void run() {
				// 쓰레드 수행작업 
		}
}

...

Runnable run = new TestRunnable();
Thread thread = new Thread(run); // 쓰레드 생성

thread.start(); // 쓰레드 실행

왜 Thread 직접 상속받지 않고 Runnable 사용해 쓰레드 구현할까?

→ 클래스와 인터페이스의 차이 (Java는 다중 상속 지원 X)

📌 람다식

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> { // 쓰레드 수행 작업
            int sum = 0;
            for (int i = 0; i < 50; i++) {
                sum += i;
                System.out.println(sum);
            }
            System.out.println(Thread.currentThread().getName() + " 최종 합 : " + sum);
        }; // 현재 실행 중인 쓰레드 이름 반환

        Thread thread1 = new Thread(task);
        thread1.setName("thread1"); // 쓰레드에 이름 부여
        Thread thread2 = new Thread(task);
        thread2.setName("thread2");

        thread1.start();
        thread2.start();
    }
}

📌 데몬 쓰레드

  • background에서 실행되는 낮은 우선순위 가진 쓰레드
public class Main {
    public static void main(String[] args) {
        Runnable demon = () -> {
            for (int i = 0; i < 1000000; i++) {
                System.out.println("demon");
            }
        };

        Thread thread = new Thread(demon);
        thread.setDaemon(true); // true로 설정시 데몬스레드로 실행됨

        thread.start();

        for (int i = 0; i < 100; i++) {
            System.out.println("task");
        }
    }
}
  • demon 쓰레드는 우선순위 낮고 다른 쓰레드 모두 종료되면 강제 종료 당하기 때문에 main() 쓰레드의 task가 100번 먼저 찍히면 종료되어 1000000번 수행 되지 않고 종료

📌 사용자 쓰레드

  • foreground에서 실행되는 높은 우선순위 가진 쓰레드

  • 메인 쓰레드

  • 기존에 만들었던 쓰레드들이 다 사용자 쓰레드

  • JVM은 사용자 쓰레드 작업 끝나면 데몬 쓰레드도 자동 종료 시킴

📌 쓰레드 우선순위

  • setPriority()
Thread thread1 = new Thread(task1);
thread1.setPriority(8); // 1~10 우선순위 지정
  • getPriority()
int threadPriority = thread1.getPriority();
System.out.println("threadPriority = " + threadPriority);
  • 우선순위 높다고 반드시 쓰레드 먼저 종료 X 확률이 높을 뿐

📌 쓰레드 그룹

// ThreadGroup 클래스로 객체를 만듭니다.
ThreadGroup group1 = new ThreadGroup("Group1");

// Thread 객체 생성시 첫번째 매개변수로 넣어줍니다.
// Thread(ThreadGroup group, Runnable target, String name)
Thread thread1 = new Thread(group1, task, "Thread 1");

// Thread에 ThreadGroup 이 할당된것을 확인할 수 있습니다.
System.out.println("Group of thread1 : " + thread1.getThreadGroup().getName());

회고

공부할수록 어려워지는 것 같은 Java..
강의랑 강의자료 말고도 책으로 한 번 훑고 과제 시작해야겠다.

0개의 댓글