본문 바로가기
Java

Java_5주차-(1)

by shulk 2023. 10. 16.

1. Thread 와 Runnable

*java에서 제공하는 Thread 클래스를 상속받아 쓰레드를 구현해준다.

*run()메소드에 작성된 코드가 쓰레드가 수행할 작업이다

Thread

 

*java에서 제공하는 Runnable 인터페이스를 사용하여 쓰레드를 구현해준다.

Runnable

 

1. 싱글 쓰레드

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
        	System.out.println(Thread.currentThread().getName()); // 쓰레드 이름을 출력 (main출력)
            for (int i = 0; i < 100; i++) {
                System.out.print("$");
            }
        };

		System.out.println(Thread.currentThread().getName()); // (thread1출력)
        Thread thread1 = new Thread(task);
        thread1.setName("thread1");  // setName()은 쓰레드의 이름을 설정하는거다.

        thread1.start();    // 메인 말고 다른 쓰레드를 시작하게할때 
    }
}

 

2. 멀티 쓰레드

* 동시에 실행해서 순차적으로 처리하는게 아니다. ****나오다가$$$$$$$********등 랜덤으로 출력된다.

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("$");
            }
        };
        Runnable task2 = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("*");
            }
        };


        Thread thread1 = new Thread(task);
        thread1.setName("thread1");
        Thread thread2 = new Thread(task2);
        thread2.setName("thread2");

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

 

3. 데몬 쓰레드

* 보이지 않는곳(background) 에서 실행되는 낮은 우선순위를 가진 쓰레드를 말한다.

* 보조적인 역할을 담당하며 대표적인 데몬 쓰레드로는 메모리 영역을 정리해주는 가비지 컬렉터(GC)가 있다.

 

*우선 순위가 낮고, setDaemon(true) 하면 데몬 쓰레드로 설정 한다는거다.

*Main쓰레드는 다른 다른 쓰레드 끝날때 까지 기다리지 않는다해서 우선 순위 낮은 데몬이 실행하다가 종료될 수도 있다.

*밑에 코드를 봤을때 main쓰레드인 "task" 출력 for문 끝나서  "task"가 100번 출력하는동안 "demon"은 랜덤으로 162번 출력하다 끝난다.

 

4. 사용자 쓰레드

* 보이는 곳(foregorund) 에서 실행되는 높은 우선순위를 가진 쓰레드를 말한다.

* 프로그램 기능을 담당하며 대표적인 사용자 쓰레드로는 메인 쓰레드가 있다.(메인 쓰레드 위에서 돌아간다)

* 사용자 쓰레드 만드는법 : 기존에 만들었던 쓰레드들이 다 사용자 쓰레드다. (위 싱글,멀티 쓰레드에 thread1 ,thread2)

* JVM 은 사용자 쓰레드의 작업이 끝나면 데몬 쓰레드도 자동으로 종료시켜 버린다.

 

5. 쓰레드의 우선순위 정하기

* setPriority(1~10); 으로 해당 쓰레드 우선순위 정한다. (1~10까지 정할수 있고,숫자 높을 수록 우선순위 높다) 

* 우선순위의 범위는 OS가 아니라 JVM에서 설정한 우선순위이다.

* 우선순위 정한다고 무조건 우선순위 높은게 먼저 다 처리하는 것도 아니고,가벼운 코드에서는 별로 영향이 없고 무거운 코드에서 영향이 크다. 

* getPriority() 로 우선순위를 반환하여 확인할 수 있다.

 

6. 쓰레드 그룹

main쓰레드에 100개의 하위 쓰레드가 있다 할때 100개의 쓰레드를 다 관리 하기 힘드니 몇개씩 그룹으로 묶어서 

어떤 그룹을 한꺼번에 종료키거나,잠깐 멈추게 하거나 이런 처리가 가능하다.

* ThreadGroup group1 = new ThreadGroup("Group1"); 이렇게 그룹을 만들고 쓰레드 생성할때 생성자 매개변수에 그룹을 넣어준다.

* 이렇게  쓰레드를 그룹하는 이유는 만약 그룹을 안했을때 100개의 쓰레드를 모두 일시정지해야 한다면 일지정지 코드 100줄을 적어야해서 그렇다.

 

* 밑에 코드에 while문 조건 코드를 해석해보면

각 쓰레드가 맨밑에 있는 코드interrupt()인 인터럽트가 호출되기전까지 무한 반복 수행하라는 거다

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    break;
                }
            }
            System.out.println(Thread.currentThread().getName() + " Interrupted");
        };

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

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

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

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

        try {
            // 현재 쓰레드를 지정된 시간동안 멈추게 합니다.
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // interrupt()는 일시정지 상태인 쓰레드를 실행대기 상태로 만듭니다.
        group1.interrupt();

    }
}

 

7. sleep()

* 현재 쓰레드를 지정된 시간동안 멈추게 하고,쓰레드 자기자신에 대해서만 멈추게 할 수 있다.

* sleep 상태에 있는 동안 interrupt() 를 만나면 다시 실행되기 때문에 InterruptedException이 발생할 수 있어서 예외처리 해야한다.

* sleep은 static형이라 객체.메소드()형태말고 static메소드 사용 하던데로 클래스명.메소드()인 Tread.sleep() 한다.

* 특정 쓰레드를 지목해서 멈추게 하는 것은 불가능하다.

(6번 설명 코드에 5초 일시정지 부분 보면 이거는 Main쓰레드를 일시 정지 하는거다. 사용자 쓰레드를 일시 정지 하게 하려면 Runnable tast에 적어야한다. 해석해보면 사용자 쓰레드 객체 메소드에서 일시정지 코드 적는거 아닌이상 다른곳에서 sleep()하면 Main쓰레드 일시정지인듯)

 

8. interrupt()

* 일시정지 상태인 쓰레드를 실행대기 상태로 만든다.

* isInterrupted()를 사용하면 interrupt된 상태인지 true,false 리턴한다.

'Java' 카테고리의 다른 글

Java_5주차-(2)  (0) 2023.10.17
Java_4주차  (0) 2023.10.16
Java_3주차-(2)  (0) 2023.10.13
Java_3주차-(1)  (0) 2023.10.13
Java_2주차  (0) 2023.10.12