TIL) Java - 쓰레드(Thread)

oatraspberry·2022년 12월 15일
post-thumbnail

프로세스

실행 중인 프로그램, 자원(resources)과 쓰레드로 구성

쓰레드(Thread)

프로세스(process) 내에서 실제로 작업을 수행하는 주체
모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다.
CPU를 사용하는 최소 단위.

프로세스 : 쓰레드 = 공장 : 일꾼

Thread는 동시성(Concurrency)과 병렬성(Parallelism)을 가지고 수행

쓰레드 상태

객체 생성

  • NEW 스레드 객체가 생성, 아직 start() 메소드가 호출되지 않은 상태

실행 대기

  • RUNNABLE 실행 상태로 언제든지 갈 수 있는 상태

  • start() 이후 CPU를 사용할 수 있는 상태

  • 다른 Thread들과 동시성(concurrency)에 따라 실행과 실행대기를 교차함

  • TIMED_WAITING
    일정시간 일시정지 상태를 나타내며 이 상태에서는 CPU를 사용할 수 없음.

    • Thread.sleep(1000): sleep(시간)을 호출한 쓰레드가 설정한 시간동안 일시정지상태 유지
    • join(1000): thread1.join(시간)을 호출하면 지정시간동안 thread1이 CPU를 사용하여 호출한 쓰레드는 일시정지 상태
  • BLOCKED

  • WAITING
    Object 메서드, wait()을 호출한 메서드는 일시정지 상태가 되며 다른 쓰레드가 notify(), notifyAll()로만 깨울 수 있음. (wait() 다음 줄부터 실행)
    동기화 메서드, 동기화 블록 내에서만 사용 가능.

    • notify(): 하나의 쓰레드를 깨움.
    • notifyAll(): wait()중인 모든 Thread를 깨움.

종료

  • TERMINATED run() 메서드의 작업내용이 모두 완료되어 Thread가 종료된 상태
  • 한번 실행(start())된 Thread는 재실행은 불가하며 새롭게 객체를 생성하여야 함

싱글 쓰레드 프로세스

자원 + 쓰레드
싱글 쓰레드는 사용자로부터 입력을 기다리는 구간에 아무 일도 하지 않는다.

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("|");
        }
   	} // main}
}      

멀티 쓰레드 프로세스

자원 + 쓰레드 + 쓰레드 + ... + 쓰레드
대부분의 프로그램이 멀티쓰레드로 되어 있다.
두 개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스(multi-threaded process)라고 함.
멀티 쓰레드는 사용자로부터 입력을 기다리는 구간에 다른 쓰레드를 수행한다.
사용자의 입력을 기다리는 동안 다른 쓰레드가 작업을 처리할 수 있기 때문에 보다 효율적인 CPU의 사용이 가능함.

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("-");
        }
   } // run()
}

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

장점

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

단점

  • 동기화(synchronization)에 주의해야 한다.
  • 교착상태(dead-lock)가 발생하지 않도록 주의해야 한다.
  • 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다.

쓰레드 상태

  • Thread 상태

  • born 상태
    Thread 객체를 생성만 한 상태이며 아직 시작은 되지 않은 상태

  • ready(=runnable) 상태
    Thread 객체에 start() 메소드를 호출한 상태
    아직 CPU에 스케줄링 되어 실행되지는 않는다.

쓰레드 구현

  1. Thread 클래스를 상속
class MyThread extends Thread {
	public void run() { // Thread 클래스의 run()을 오버라이딩, 쓰레드가 수행할 작업을 작성
    	/* 작업 내용 */
    }
}
MyThread t1 = new MyThread(); // 쓰레드의 생성
t1.start(); // 쓰레드의 실행
*자바는 단일상속
  1. Runnable 인터페이스를 구현
class MyThread2 implements Runnable {
	public void run() { // Runnable 인터페이스의 추상메서드 run()을 구현, 쓰레드가 수행할 작업을 작성
    	/* 작업 내용 */
   }
}
Runnable r = new MyThread2(); // 쓰레드의 생성
Thread t2 = new Thread(r); // Thread(Runnable r)
// Thread t2 = new Thread(new MyThread2()); // 위 두줄을 한줄로 생략
t2.start(); // 쓰레드의 실행

Runnable

쓰레드의 실행 - start()

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

ThreadEx1_1 t1 = new ThreadEx1_1(); // 쓰레드 t1을 생성한다.
ThreadEx1_1 t2 = new ThreadEx1_1(); // 쓰레드 t2을 생성한다.

t1.start(); // 쓰레드 t1을 실행시킨다.
t2.start(); // 쓰레드 t2을 실행시킨다.

주의1)
재정의한 메서드는 run()이지만 Thread의 실행은 start()메서드 호출
주의2)
Thread 객체는 재사용 할 수 없음. (-> 하나의 객체는 한번만 start() 가능)

main쓰레드

main메서드의 코드를 수행하는 쓰레드

  • 사용자 쓰레드: 메인 쓰레드
  • 데몬 쓰레드: 보조 쓰레드

실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다.

쓰레드의 I/O 블락킹(blocking)

Input 입력 / Output 출력 = 입출력
블락킹 = 입출력시 작업 중단되는 것

출처 - 자바의 정석

profile
개발자가 될테야

0개의 댓글