Java의 Thread(2)

Dohyeon Kong·2024년 4월 6일

Java☕

목록 보기
11/12
post-thumbnail

Java Thread

자바 스레드는 일반 스레드와 별반 차이가 없으며 자바 가상 기계(JVM)이 운영체제 역할을 한다.

  • 자바에는 프로세스가 존재하지 않고 스레드만 존재하며, 자바 스레드는 JVM에 의해 스케줄 되는 실행 단위 코드 블록이다.
  • JVM은 하나의 자바 응용프로그램만 실행이 가능하며, 하나의 응요프로그램이 여러 개의 스레드를 가질 수있다.
  • 스레드 스케줄링은 JVM에서 이루어지며, 스레드가 몇개인지, 스레드로 실행되는 프로그램 코드의 메모리 우치는 어디인지, 스레드의 우선순위는 얼마인지 등 많은 정보는 JVM이 관리한다.

Java 스레드 만들기 방법

  • Thread 클래스 이용
  • Runnable 인터페이스 이용

Thread 클래스로 스레드 만들기

  • Thread 클래스의 경로명은 java.lang.Thread이며, Thread 클래스를 상속받아 새로운 스레드 코드를 만든다.

Thread 클래스의 주요 메소드

  • void run() : 스레드 코드로서 JVM에 의해 호출된다. 개발자는 반드시 이 메소드를 오버라이딩하여 스레드 코드를 작성해야 한다.
  • void start() : JVM에게 스레드 실행을 시작하도록 요청한다.

Thread 클래스를 상속바당 run() 오버라이딩

class TimerThread extends Thread{
	@Override
    public void run(){ // thread 클래스의 run() 오버라이딩
    	......
    }
}
  • 자바에서 스레드가 수행할 작업 코드를 반드시 run()메서드에 작성하도록 한다.
  • JVM이 스레드를 실행시키면 스레드는 run()메서드에서부터 실행을 시작되고 run()이 종료되면 스레드도 종료된다.
  • run()을 스레드 코드라고 한다.

1. 스레드 객체 생성

TimerThread th = new TimerThread(); // 스레드 객체 생성
  • TimerThread객체를 생성한 것이지 스레드를 작동시킨 것 아니다.

2. 스레드 시작 : start() 메소드 호출

th.start();
  • Thread 클래스의 start()를 호출하여 JVM이 스레드 th를 스케줄링하도록 한다.
  • start()메서드는 Thread에 클래스에 구현되어 있는 메소드로서, 스레드 객체 th를 JVM에게 새로운 스레드로 인식하고 스케줄링 가능한 상태로 만들 것을 지시한다.
  • JVM이 이 스레드를 스케줄링하면, 그떄 비로소 스레드 th의 run()가 실행된다.
  • 개발자가 start()메소드를 절대 오버라이딩 하면 안된다.
sleep() 메소드
  • 인자값에 따라 스레드의 작동을 일시정지시키는 코드이다.
  • 일시정지동안 이 스레드를 종료시키고자 하는 예외 InterruptedException이 발생할 떄 이를 처리하기 위해 try-catch블록이 삽입되어야 한다.
  • try-catch문 없이 sleep()문을 사용하면 자바 컴파일러는 오류를 발생시킨다.
// Java 스레드 예시 코드
class TimerThread extends Thread{
	int n = 0;
    
    @Overide
    public void run(){
    	whlie(true){
        	System.out.println(n);
            n++;
            try{	
            	sleep(1000);
            }
            catch(InterruptedException e){
            	return;
            }
        }
    }
}

public class TestThread{
	public static void main(String[] args){
    	TimerThread th = new TimerThread();
        th.start();
	}
}

// ** 실행 결과 **
// 0
// 1
// 2
// 3
// 4
// .
// .
// .

Runnable 인터페이스로 스레드 만들기

  • Runnable의 경로명은 java.lang.Runnable이며,추상 메서드 run()만 가진 인터페이스이다.
interface Runnable{
	public void run();
}

1. 스레드 클래스 선언 : Runnable 인터페이스 구현

class TimerRunnable implements Runnable{

	@Override
    public void run(){ // Runnable 인터페이스의 run() 메소드 오버라이딩
   		.......... 
    }
}
  • run() 메소드에 스레드 코드를 구현한다. run()이 종료되면 스레드도 종료된다.

2. 스레드 객체 생성

  • run()을 오버라이딩한 TimerRunnable의 인스턴스를 생성하고, 다음과 같이 Thread 클래스의 생성자에 전달하면서 스레드 객체를 생성한다.
Thread th = new Thread(new TimerRunnable()); // 스레드 객체 생성

3. 스레드 시작 : start() 메소드 호출

th.start();
  • Thread 클래스의 start()를 호출하여 JVM이 스레드 th를 스케줄링하도록 한다.
  • start()메서드는 Thread에 클래스에 구현되어 있는 메소드로서, 스레드 객체 th를 JVM에게 새로운 스레드로 인식하고 스케줄링 가능한 상태로 만들 것을 지시한다.
  • JVM이 이 스레드를 스케줄링하면, 그떄 비로소 스레드 th의 run()가 실행된다.
  • 개발자가 start()메소드를 절대 오버라이딩 하면 안된다.

Thread 종료

  • 스스로 종료: run()메소드가 종료하거나 리턴하는 경우
  • 강제 종료 : interrupt() 메소드를 호출, IntterruptedException 예외가 발생하기 때문에 try-catch문을 사용한다.

Thread 동기화

멀티스레드 프로그램이 실행될 때, 다수의 스레드가 공유 데이터를 동시에 접근하는 경우가 발생하는데 여러 스레드에 의해 공유 데이터의 값이 비정상적으로 유지되지 않도록 스레드의 실행을 제어하는 기술

Thread 동기화 방법

    1. sychronized로 동기화 블록 지정
    1. wait() - notify() 메서드로 스레드 실행 순서 제아

sychronzied 블록

코드 블록을 동기화가 설정된 임계 영역으로 지정하는 방법이 있으며, 메소드를 임계 영역으로 지정하는 방법과 임의의 코드 블록만 지정하는 방법이 있다.

// 1. 메소드를 임계 영역으로 지정하는 방법
sychronized void print(String text){
	...
    for(int i = 0; i < text.length(); i++){
    	System.out.println(text.charAt(i));
    }
}
// 2. 임의의 코드 블록만 지정하는 방법
void execute(String text){
	...
    synchronized(this){ // 동기화 코드 블록
    	...
    	for(int i = 0; i < text.length(); i++){
    		System.out.println(text.charAt(i));
    	}
    }
}

참조📜

  • 명품 JAVA ESSENTIAL - 황기태 지음-
profile
티스토리로 기술 블로그 이전

0개의 댓글