티스토리 뷰

1. Thread란?

 - Process : 프로그램이 메모리에 올라간 상태 (실행중인 프로그램), OS로부터 메모리를 할당 받음

 - Thread : 실제 프로그램이 수행되는 작업의 최소 단위, 하나의 프로세스(프로그램)는 하나 이상의 Thread를 가지게 되어 CPU를 점유함

 - 스케쥴러가 CPU를 점유하여 쓰레드에 CPU를 할당하여 쓰레드를 실행시킴.

 - *멀티 쓰레드 : 하나의 프로세스안에 두 개의 Thread가 동시에 돌아가는 것 처럼 보이는 것

 2. Thread 구현하기

  1) Thread 클래스로 부터 상속받아 구현

package thread;

class MyThread extends Thread {
    
    public void run() { //쓰레드가 start되면 run메서드가 실행되기 때문에 run을 구현해야 함.
        int i;
        
        for (i = 0; i <= 200; i++) {
            System.out.println(i + "\t");
            
            try {
                sleep(100); //sleep :  Thread class의 static method
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ThreadTest {
    //프로그램을 실행하면 총 3개의 쓰레드가 진행됨 (main, th1, th2)
    public static void main(String[] args) { //먼저 main쓰레드가 실행되어 start를 출력하고 th1과 th2를 띄워준뒤 end를 출력하여 먼저 끝난다. 
        
        System.out.println("start");
        MyThread th1 = new MyThread(); 
        MyThread th2 = new MyThread();
        
        th1.start(); // start() : 쓰레드 호출 명령어.
        th2.start(); //이후에 th1과 th2가 start되어 성능에따라 번갈아가면서 run메서드를 수행한다.
        System.out.println("end");

    }

}

 

  2) Runnable 인터페이스 구현

   - 자바는 다중 상속이 허용되지 않으므로, 이미 다른 클래스를 상속한 경우 thread를 만드려면 Runnable interface를 implements 한다.

package thread;

class MyThread2 implements Runnable {

    @Override
    public void run() {
            int i;
            
            for (i = 0; i <= 200; i++) {
                System.out.println(i + "\t");
                
                try {
                    Thread.sleep(100); //sleep :  Thread class의 static method
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        
    

}
public class ThreadRunnable {
    //프로그램을 실행하면 총 3개의 쓰레드가 진행됨 (main, th1, th2)
    public static void main(String[] args) { //먼저 main쓰레드가 실행되어 start를 출력하고 th1과 th2를 띄워준뒤 end를 출력하여 먼저 끝난다. 
        
        System.out.println("start");
        
        MyThread2 runner1 = new MyThread2();
        Thread th1 = new Thread(runner1);
        th1.start();
        
        MyThread2 runner2 = new MyThread2();
        Thread th2 = new Thread(runner2);
        th2.start();

        System.out.println("end");

    }

}

 

3. Thread status

 - 쓰레드가 Start가 되면, Runnable한 상태로 된다. (쓰레드는 Runnable한 상태에서만 CPU를 점유할 수 있음)

 - 스케쥴러가 CPU를 배분하여 하나의 쓰레드를 RUN 한다.

 - 쓰레드가 종료되면 Dead의 상태가 된다. 

 - 쓰레드가 CPU를 점유할 수 없는 Not Runnable 상태(실행될 수 없는 상태)로 빠지는 3가지 경우가 있음

 1) sleep(시간) : 입력한 시간동안 Not Runnable 상태로 빠짐. 

 2) wait() : Shared Resource를 기다리는 메서드

 3) join() : 2개의 쓰레드가 동시에 돌아간다고 했을 때, 한 쓰레드가 다른 쓰레드에게 join을 걸면, 다른 쓰레드가 끝날 때 까지 join을 건 쓰레드가 Not Runnable 상태에 빠짐

 - 쓰레드가 Not Runnable 상태에서 빠져나오지 못하면, Interrupt exception을 날리면, Interrupt에 의해 exception으로 빠져서 Runnable한 상태로 만들 수 있음.

 

 

4. Thread 우선순위

 - 쓰레드는 우선순위를 갖는다

 - Thread.MIN_PRIORITY(=1) ~ Thread.MAX_PRIORITY(=10)

 - 디폴트 우선 순위 : Thread.NORM_PRIORITY (=5)

 - setPriority(int newPriority)

 - int getPriority()

 - 우선 순위가 높은 thread는 CPU를 배분 받을 확률이 높음

 

 1) Thread class의 currentThread() 메서드를 통해 현재 Thread의 정보 불러오기

  - 참조변수 t를 통해 현재 Thread의 정보를 출력하면 Thread[현재 쓰레드의 이름, 우선순위, 쓰레드가 속해있는 그룹]을 알 수 있다.

 

5. join() 메서드

 - 다른 thread의 결과를 보고 진행해야 하는 일이 있는 경우 join() 메서드를 활용

 - join() 메서드를 호출한 thread가 non-runnable 상태가 됨

 

6. interrupt() 메서드

 - 다른 thread에 예외를 발생시키는 interrupt를 보냄

 - thread가 join(), sleep(), wait() 메서드에 의해 블럭킹 되었다면 interrupt에 의해 다시 runnable 상태가 될 수 있음.

package thread;

public class InterruptTest extends Thread {
    
    public void run() {
        
        int i;
        for (i = 0; i < 100; i++) {
            System.out.println(i);
        }
        
        try {
            sleep(5000);
        } catch (InterruptedException e) {
            System.out.println(e);
            System.out.println("Wake!!!");
        }
        
        for (i = 0; i < 100; i++) {
            System.out.println(i);
        }
        
        
    }

    public static void main(String[] args) {
        
        
        InterruptTest test = new InterruptTest();
        test.start();
        test.interrupt(); //run메서드에 정의된 sleep을 거치지않고 바로 Interrupt Exception으로빠져서 다음 코드를 실행함.         
        System.out.println("end");

    }

}

7. thread 종료하기 

 - 데몬등 무한 반복하는 thread가 종료될 수 있도록 run() 메서드 내의 while문을 활용

 - Thread.stop()은 사용하지 않음 

package thread;

import java.io.IOException;

public class TerminateThread extends Thread {
    
    private boolean flag = false;
    int i;
    
    public TerminateThread(String name) {
        super(name);
    }
    
    public void run() {
        while (!flag) {
            
            try {
                sleep(100);//0.1초
            } catch (InterruptedException e) {
                e.printStackTrace();
            } 
        }
        
        
        System.out.println(getName() + "end");
    }
    
    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public static void main(String[] args) throws IOException {
        
        TerminateThread threadA = new TerminateThread("A");
        TerminateThread threadB = new TerminateThread("B");
        
        threadA.start();
        threadB.start();
        
        int in;
        while (true) {
            in = System.in.read(); //enter를 입력하면 \n, \r이 입력된다.
            if (in == 'A') {
                threadA.setFlag(true);
            }
            else if (in == 'B') {
                threadB.setFlag(true);
            } 
            else if (in == 'M') {
                threadA.setFlag(true);
                threadB.setFlag(true);
                break;
            }
            else {
               // System.out.println("try again");
            }
            
        }
        System.out.println("Main End");
    }

}

 

* 운영체제 개념 공부하기

 

 

'Java > Java 올인원 패키지' 카테고리의 다른 글

34. 직렬화 (Java)  (0) 2020.04.06
31. 입출력 스트림 (Java)  (0) 2020.03.24
30. 예외 처리 (Java)  (0) 2020.03.24
29. 스트림 (Java)  (0) 2020.03.23
28. 람다식 (Java)  (0) 2020.03.23
댓글