adv-study / adv1

김영한 고급 adv1
0 stars 0 forks source link

[Sec3] 쓰레드 생성과 실행 #11

Open CodingWon opened 3 weeks ago

CodingWon commented 3 weeks ago

1.자바 메모리 구조

20241111153336

2. 스레드 생성 - Thread 상속

public class HelloThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + ": run()");
    }
}
public class HelloThreadMain {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName() + ": main() start");

        HelloThread helloThread = new HelloThread();
        System.out.println(Thread.currentThread().getName() + ": start() 호출전");

        helloThread.start();

        System.out.println(Thread.currentThread().getName() + ": start() 호출후");
        System.out.println(Thread.currentThread().getName() + ": main() end");
    }
}

스레드 간 실행 순서는 보장하지 않는다.

3. 데몬 쓰레드

4. 스레드 생성 - Runnable

5. Thread 상속 vs Runnable 구현

1) Thread 상속 방식

2) Runnable 인터페이스 구현 방식

결론 - Runnable 를 사용해라 !

6. 로거 만들기

7. 여러 쓰레드 만들기

20241111162020

8. Runnable을 만드는 다양한 방법

1) 정적 중첩 클래스 사용

package thread.start;

import static util.MyLogger.log;

public class InnerRunnableMainV1 {
    public static void main(String[] args) {
        log("main() start");
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        log("main() end");
    }

    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            log("run()");
        }
    }
}

2) 익명 클래스 사용

package thread.start;

import static util.MyLogger.log;

public class InnerRunnableMainV2 {
    public static void main(String[] args) {
        log("main() start");

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                log("run()");
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();

        log("main() end");
    }
}

3) 익명 클래스 변수 없이 직접 전달

package thread.start;

import static util.MyLogger.log;

public class InnerRunnableMainV3 {
    public static void main(String[] args) {
        log("main() start");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                log("run()");
            }
        });
        thread.start();
        log("main() end");
    }
}

4) 람다

package thread.start;

import static util.MyLogger.log;

public class InnerRunnableMainV4 {
    public static void main(String[] args) {
        log("main() start");// 람다를 배우면 이해
        Thread thread = new Thread(() -> log("run()"));
        thread.start();
        log("main() end");
    }
}

9. 문제 4 : 여러 쓰레드 사용

public class StartTest4Main {
    public static void main(String[] args) {
        Thread threadA = new Thread(new PrintWork("A", 1000), "Thread-A");
        Thread threadB = new Thread(new PrintWork("B", 500), "Thread-B");
        threadA.start();
        threadB.start();
    }

    static class PrintWork implements Runnable {
        private String content;
        private int sleepMs;

        public PrintWork(String content, int sleepMs) {
            this.content = content;
            this.sleepMs = sleepMs;
        }

        @Override
        public void run() {
            while (true) { // 무한 루프
                log(content);
                try {
                    Thread.sleep(sleepMs);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
JisuPark-dev commented 2 days ago

Runnable만드는 다양한 방법에 대해서 말씀해주셨는데, 보통은 runnable 패키지를 따로 파서 거기에다가 도메인별로 필요한 작업을 모아서 관리하지 않을까요?

JisuPark-dev commented 2 days ago

오호 실제로 그렇게 한다네요. com.example.project ├── runnable │ ├── email │ │ ├── EmailSenderRunnable.java │ │ ├── EmailLoggerRunnable.java │ ├── file │ │ ├── FileUploaderRunnable.java │ │ ├── FileProcessorRunnable.java │ ├── notification │ │ ├── NotificationSenderRunnable.java │ │ ├── NotificationCleanerRunnable.java