본문 바로가기

Backend Study/Java

[JAVA] 쓰레드, 프로세스, 멀티 쓰레드

1. 프로세스와 스레드 

프로그램 : 실행 가능한 파일 (HDD, SSD) 

프로세스 : 실행중인 프로그램 (메모리), 자원과 쓰레드로 구성

쓰레드 : 프로세스 내에서 실제 작업을 수행, 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다. 

 

싱글 쓰레드 프로세스 = 자원 + 쓰레드

멀티 쓰레드 프로세스 = 자원  + 쓰레드 + 쓰레드 + 쓰레드

 

멀티 프로세싱 = 멀티 태스킹 : 동시에 여러 프로세스를 실행시키는 것

멀티 쓰레딩 = 하나의 프로세스 내에 동시에 여러 쓰레드를 실행시키는 것, 같은 프로세스 내의 쓰레드들은 서로 자원을 공유한다.

(효율적이라는 장점이 있지만, 동기화나 교착상태에 신경써야한다.)

 

멀티 스레드로 구현된 프로그램을 실행하면? 

- 하나의 프로세서는 한번에 스레드 1개밖에 실행시키지 못한다.

- 대신 일정한 간격으로 수행해야하는 스레드를 전환한다.

- 스레드를 전환할때는 운영체제의 스케줄러의 기준에 따라 순서가 정해지게된다.

- 여러 스레드를 번갈아 처리하기때문에 동시에 작업하는 듯한 효과를 준다 = 시분할 방식

2. 스레드의 생명 주기

Runnable (준비 상태)=ready:

스레드가 실행되기 위한 준비단계이다. CPU를 점유하고 있지 않으며 실행(Running상태)가 되기위해 대기하고 있는 상태이다. 코딩상에서 start() 메소드를 호출하면 run() 메소드에 설정된 스레드가 Runnable 상태로 진입한다.

 

Running (실행 상태):

CPU를 점유하고 실행하고 있는 상태이며, run() 메서드는 JVM만이 호출 가능하다. ready 상태에 있는 여러 스레드 중 우선 순위를 가진 스레드가 결정되면 JVM이 자동으로 run() 메소드를 호출한다.

 

Dead (종료 상태):

Running 상태에서 스레드가 모두 실행되고 난 후 완료 상태이다.

 

Blocked (지연 상태):

CPU를 점유권을 상실항 상태이다. 특정 메서드를 실행시켜 Runnable (준비상태)로 전환한다.

wait() 메서드에 의해 blocked가 되면 notify() 메서드 호출 시 Runnable 상태가 되고, sleep() 메서드에 의해 blocked 상태가 되면 시간이 지난 후 Runnable 상태로 간다.

3. 자바로 스레드 생성하기

스레드를 생성하는 방법은 두가지이다. 

1) Thread 클래스 상속받아서 생성

2) Runnable 인터페이스 구현하여 생성

 

Thread 클래스 상속: 

java.lang.Thread 클래스를 상속받아서 run() 메서드 오버라이딩

start() 메서드를 통해 스레드가 시작된다.

 

public class Test extends Thread{
    @Override
    public void run() {
    }
}

 

Runnable 인터페이스 구현: 

java.lang.Runnable 인터페이스로부터 run() 메서드를 구현하여 생성한다.

 

public class Test implements Runnable {
    @Override
    public void run() {
    }
}

 

4. 싱글쓰레드 VS 멀티쓰레드

/* 싱글쓰레드 */
class ThreadTest {
	public static void main (String args[]){
    	for (int i=0; i<300; i++){
        	System.out.println("_");
        }
        
        for (int i=0; i<300; i++){
        	System.out.println("l");
        }
    
    }
}

/* 멀티쓰레드 */
class ThreadTest {
	public static void main(String args[]){
    	MyThread1 th1 = new MyThread1();
        MyThread2 th2 = new MyThread2();
        th1.start();
        th2.start();
    }
}

class MyThread1 extends Thread {
	public void run() {
    	for (int i=0; i<300; i++){
        	System.out.println("쓰레드1");
        }
    }
}

class MyThread2 extends Thread {
	public void run() {
		for (int i=0; i<300; i++){
        	System.out.println("쓰레드2");
        }    
    }
}

 

참고)https://coding-factory.tistory.com/279