본문 바로가기

👩‍💻 BackEnd/☕️ 자바 [Java]

멀티 스레드와 싱글 스레드, 스레드의 IO블로킹, 쓰레드 그룹

A작업에서 B 작업으로 넘어가는 것을 Context Switching (문맥전환)이라고 함. 이때 시간이 소요됨. 

 

멀티스레드의 장점 

  • 시간이 조금 걸리더라도 하나의 작업을 수행하면서 다른 작업을 동시에 수행할 수 있다는 점이 장점. 
  • 작업을 조금 더 효율적으로 처리할 수 있다. (IO블로킹 : 입출력 시 작업이 중단되는 것을 말함).
  • 싱글 스레드일 경우 사용자로부터 입력을 받는 동안 IO 블로킹으로 인해 아무 작업도 할 수 없지만, 멀티 스레드로 돌릴 경우, IO 블로킹이 일어나지 않아 작업을 더 빠르고 효율적으로 처리할 수 있음. 
  • 입출력 작업이 완료될 때까지 프로그램이 기다리는 것.

 

싱글 스레드의 예제 

 

package ch13;

import javax.swing.*;

// 싱글스레드
public class Ex13_4 {
    public static void main(String[] args) {
        String input = JOptionPane.showInputDialog("아무 값이나 입력하세요");
        System.out.println("입력하신 값은 " + input + "입니다. ");

        for (int i = 10; i > 0; i--) {
            System.out.println("i = " + i);
            try {
                Thread.sleep(1000); // 1초의 시간을 지연
            } catch (Exception e) {}
        }
    }
}

 

 

멀티 스레드의 예제 

package ch13;

import javax.swing.*;

// 멀티 스레드
public class Ex13_5 {
    public static void main(String[] args) {

        ThreadEx5_1 th1 = new ThreadEx5_1();
        th1.start();

        String input = JOptionPane.showInputDialog("아무 값이나 입력하세요");
        System.out.println("입력하신 값은 " + input + "입니다.");
    }
}

class ThreadEx5_1 extends Thread{

    @Override
    public void run() {
        for (int i = 10; i > 0; i--) {
            System.out.println("i = " + i);

            try {
                sleep(1000);

            } catch (Exception e) {

            }
        }
    }
}

 

두 작업을 실행 시켜보면 

싱글스레드인 경우에는 값을 입력해야 다음 작업으로 for문이 돌아가면서 i의 값이 콘솔에 출력된다. 

 

하지만 멀티스레드인 경우에는 값을 입력하지 않아도 for 문이 다른 스레드 작업으로 돌아가기 때문에 for 문이 돌아가면서 i의 값이 콘솔에 출력되게 된다.

 

입력을 하지 않았음에도 콘솔에 i의 값이 찍히는 모습 (멀티스레드)

 


스레드의 우선 순위 

작업의 중요도에 따라 스레드의 우선순위를 다르게 하여 특정 스레드가 더 많은 작업 시간을 갖도록 할 수 있다. 

 

void setPriority(int priority)	// 스레드의 우선순위 지정 
int getPriority()				// 스레드의 우선순위 반환

 

 

package ch13;

public class Ex13_6 {
    public static void main(String[] args) {

        ThreadEx6_1 th1 = new ThreadEx6_1();
        ThreadEx6_2 th2 = new ThreadEx6_2();

        th1.setPriority(5);
        th2.setPriority(7);

        System.out.println("Priority of th(-) : " + th1.getPriority());
        System.out.println("Priority of th(|) : " + th2.getPriority());
        th1.start();
        th2.start();
    }
}


class ThreadEx6_1 extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 300; i++) {
            System.out.println("-");
            for (int j = 0; j < 10000000; j++) {
                
            }
        }
    }
}

class ThreadEx6_2 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 300; i++) {
            System.out.println("|");
            for (int j = 0; j <10000000; j++) {

            }
        }
    }
}

 

우선순위를 지정해 주지만 OS 마다 각각 우선순위가 매겨져 있어서 꼭 우리가 자바 코드로 매긴 우선순위를 따라 실행되지 않지만,

그래도 여러번 실행하면 어느 정도 반영이 되는 모습을 발견할 수 있다. 

 

 

쓰레드 그룹 

  • 서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것
  • 모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함되어 있어야 한다. 
  • 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 'main쓰레드 그룹'에 속한다. 
  • 자신을 생성한 쓰레드(부모쓰레드)의 그룹과 우선순위를 상속받는다.