ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] Process & Thread (프로세스와 스레드) 알아보기
    JAVA 2022. 9. 5. 15:32
    728x90
    반응형

    프로세스와 스레드 구분하기

    모든 프로세스는 최소한 1개 이상의 스레드를 가지고 있다.

    프로세스(공장) : 실행 중인 프로그램, 자원(resources)과 스레드로 구성되어있다.

    • 자원은 메모리, cpu.. 등등
    • 메모리에는 프로세스에 필요한 소스코드, static 멤버, heap(동적 메모리 영역), stack(지역변수, 매개변수, 반환 값 등 일시적인 데이터) 공간을 확보한다.
    • 프로세스 생성 시 PCB블록이 함께 생성된다.

    스레드(일꾼) : 프로세서 내에서 실제 작업을 수행하는 것을 말한다.

    • 경량화된 프로세스 : 스레드는 프로세스의 소스코드, static멤버, heap을 공통된 자원으로 사용한다.
      • 스레드는 stack만 별도로 가지고 있다.
    • 싱글 스레드 : 자원 + 스레드 1
    • 멀티 스레드 : 자원 + 스레드 1 + 스레드 2 + 스레드 3... + 스레드 N
      • 실제 프로그램은 멀티 스레드로 만들어진다.

    멀티 스레드의 장단점

    장점

    • 시스템 자원을 보다 효율적으로 사용할 수 있다.
    • 사용자에 대한 응답성이 향상된다.
    • 작업이 분리되어 코드가 간결해진다.

    단점

    • 동기화에 주의해야 한다.
    • 교착상태(dead-lock)가 발생하지 않도록 주의해야 한다.
      • 위 두 개의 단점은 각 스레드가 자원을 공유하다가 발생할 수 있는 문제이다.
    • 각 스레드가 효율적으로 고르게 실행될 수 있게 해야 한다.

    스레드의 구현과 실행

    스레드의 경우 상속(extends)과 구현(implements) 두 가지 방법이 있다.

    • Thread 클래스 상속으로 생성 및 사용
    class Thread_extends extends Thread{
        public void run(){ // Thread 클래스의 run() 오버라이딩
            // 작업내용
        }
    }
    
    Thread_extends th1 = new Thread_extends(); // 스레드 생성
    th1.start(); // 스레드 실행
    • Runnable 인터페이스로 구현 및 사용
    class Thread_implements Runnable{
        public void run(){ // Runnable 인터페이스의 추상 메서드 run() 구현
            // 작업내용
        }
    }
    
    Runnable r = new Thread_implements();
    Thread th2 = new Thread(r); // 스레드 생성
    // Thread th2 = new Thread(new Thread_implements); // 위 두줄을 한줄로 작성하기
    th2.start(); // 스레드 실행

    스레드 실행 - start( )

    스레드를 생성한 후에 start()를 호출해야 스레드가 작업을 시작한다.

    ThreadEX1 th1 = new ThreadEx1();
    ThreadEX1 th2 = new ThreadEx1();
    
    th1.start();
    th2.start();
    • start()는 시작이 아닌 시작한 준비를 완료한 것이다.
    • th1, th2 중에 어느 게 먼저 실행될지는 OS스케줄러가 결정한다.
    • th1이 먼저 start()했다고 먼저 사용된다는 보장은 없다.

    start()

    예제로 알아보기

    class ThreadEx1 extends Thread{
        public void run(){
            for(int i = 0; i < 100; i++){
                System.out.print(0);
            }
        }
    }
    
    class ThreadEx2 implements Runnable{
        public void run(){
            for(int i = 0; i < 100; i++){
                System.out.print(1);
            }
        }
    }
    
    ThreadEx1 th1 = new ThreadEx1();
    Thread th2 = new Thread(new ThreadEx2());
          
    th1.start();
    th2.start();
    // 결과 (순서가 보장되지 않는다.)
    // 00001011111001010001011100....

    main 스레드

    스레드의 종류는 사용자 스레드와 데몬 스레드(보조 스레드)가 있다.

    • 실행 중인 사용자 스레드가 없을 경우 프로그램이 종료된다.
    • 멀티 스레드의 경우 main 스레드가 종료돼도 다른 스레드가 있기 때문에 종료되지 않는다.

    context switching

    멀티 스레드에서 A에서 B로 넘어갈 때 소요되는 시간을 말한다.

    context-switching

    • 멀티 스레드가 싱글 스레드 보다 최종 소요시간이 더 걸린다.

    왜 시간이 더 걸리는 멀티 스레드를 사용할까?

    이유는 소요시간이 조금 더 걸리더라도 여러 가지 작업을 동시에 진행할 수 있기 때문입니다.

    • 예를 들어 파일을 다운로드하면서 채팅을 하는 것이다.

    스레드의 I/O 블로킹(blocking)

    입력 출시 작업이 중단되는 것을 말한다.

    // 싱글 스레드
    String input = JOPtionPane.showInputDialog("값을 입력하세요.");
    System.out.println("입력하신 값은 " + input + "입니다.");
    
    for (int i = 10; i > 0; i--){
        System.out.println(i);
        try{
            Thread.sleep(100); // 1초 지연
        }catch(Exception e){}
    }
    // 결과
    // 입력하신 값은 1 입니다.
    // 10
    // 9
    // 8 ...
    • 이때 input을 입력하지 않으면 작업 중단(I/O 블로킹)이 된다.
    • 입력이 완료되면 그때부터 아래 있는 코드들이 실행된다.

    I/O 블로킹을 해결하기 위해 멀티 스레드로 만들기

    class ThreadM extends Thread{
         public void run(){
             for(int i = 10; i > 0; i--){
                 System.out.println(i);
                 try{
                     sleep(1000);
                 }catch(Exception e){}
             }
         }
    }
    
    ThreadM th1 = new ThreadM();
    th1.start();
    
    String input = JOptionPane.showInputDialog("값을 입력하세요.");
    System.out.println("입력하신 값은 " + input + "입니다.");
    • 카운트 다운과 입력창이 같이 실행된다.
    • 입력하지 않아도 카운트 다운은 된다.
    728x90
    반응형
Designed by Tistory.