Java 에서 Thread 는 동시에 여러 작업을 수행 할 수 있도록 지원하는 중요한 기능이다. Thread를 사용하면 하나의 프로그램이 동시에 여러 작업을 병렬로 처리할 수 있어 시스템 자원을 효율적으로 사용할 수 있다.
1. Thread 란?
프로그램의 흐름을 나누어 동시에 실행 될 수 있는 경량 프로세스이다. Java 프로그램은 기본적으로 하나의 메인 Thread 에서 시작되며, 추가적으로 여러 스레드를 생성하여 병렬 작업을 처리할 수 있다. 각 Thread 는 독립적인 실행 흐름을 가지며, CPU 의 스케줄링에 따라 번갈아 실행된다.
2. Thread 생성 방법
Java 에서 Thread 를 생성하는 방법은 두가지가 있다.
첫 번째. Thread 클래스 상속
- Thread 클래스를 상속받아 새로운 클래스를 정의하고, run() 메서드를 오버라이딩 한다.
- run() 메서드 안에 스레드가 수행할 작업을 정의하고, start() 메서드를 호출해 스레드를 실행한다.
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 스레드를 실행
}
}
두 번째. Runnable 인터페이스 구현
- Runnable 인터페이스를 구현하고, run() 메서드를 오버라이딩하여 Thread 에서 실행 할 작업을 정의
- Thread 생성자에 Runnable 객체를 전달하여 Thread 를 생성한 뒤 start() 메서드로 실행
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable thread is running");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // 스레드를 실행
}
}
Runnable 인터페이스를 사용하는것이 더 권장된다. Java 는 다중 상속을 지원하지 않으므로, 다른 클래스를 상속해야 할 때 유연성이 높다.
3. Thread 의 주요 메서드
- start() : Thread를 시작하며, run() 메서드를 호출하여 작업 수행
- run() : Thread 가 시작되면 실행되는 메서드로, 이곳에 스레드가 수행할 작업을 정의
- sleep(long millis) : Thread 를 지정된 시간동안 멈추게한다.
- join() :다른 Thread 가 종료될 때까지 현재 Thread 를 대기 상태로 만든다.
- yield() : 실행중인 Thread 가 CPU를 다른 Thread 에 양보하도록 요청
- interrupt() : Thread 의 sleep() 이나 wait() 상태를 중단시킨다.
- isAlive() : Thread 실행 중인지 여부를 반환
4. Thread 의 Life Cycle
- NEW : Thread 객체가 생성되었지만, start() 메서드가 호출되지 않은 상태
- RUNNABLE : start() 가 호출 된 후 실행 대기 상태. CPU를 할당 받으면 실행된다.
- BLOCKED : Thread가 동기화 블록에 의해 대기 상태에 있는 경우
- WAITING : wait() 메서드 호출로 인해 다른 스레드가 작업을 완료하기 까지 대기상태가 된 경우
- TIMED_WAITING : sleep(), wait(long timeout) 메서드 호출로 인해 특정 시간 동안 대기 상태 된 경우
- TERMINATED : run() 메서드가 종료되었거나 예외로 인해 Thread 가 종료된 상태
5. 동기화(Synchronization)
동시에 여러 Thread 가 동일한 자원에 접근할 때는 동기화가 필요하다. 동기화를 통해 자원에 대한 일관성을 유지할 수 있다.
synchronized 블록
- synchronized 키워드를 사용하여 특정 메서드나 블록을 동기화 할 수 있다.
- 한 Thread가 synchronized 블록을 실행 중이면 다른 Thread는 해당 자원에 접근할 수 없다.
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
6. 교착상태(Deadlock)
Thread 간의 자원 사용이 순환 대기 상태에 빠질 때 교착 상태가 발생 할 수 있다. 이는 여러 Thread가 서로 자원을 점유하고 대기할 때 발생하며, 프로그램이 정지될 수 있다. synchronized 블록을 사용할 때 주의가 필요하다.
7. Thread pool
Java 에서 여러 Thread 를 효율적으로 관리하기 위해 ThreadPool을 제공한다. ThreadPool 은 미리 생성된 Thread 묶음으로, 반복적인 작업을 병렬로 처리할 때 성능을 높인다. Java에서 ExecutorService를 사용하여 ThreadPool 을 쉽게 만들 수 있다.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5); // 5개의 스레드를 갖는 스레드 풀
for (int i = 0; i < 10; i++) {
executor.submit(() -> System.out.println("Thread is running"));
}
executor.shutdown(); // 스레드 풀 종료
}
}
8. 멀리스레드(Multi Thread) 장점 및 주의점
장점
- 응답성이 향상된다. 하나의 작업이 느리더라도 다른 Thread 가 작업을 수행할 수 있다.
- 멀티코어 CPU에서 병렬 작업을 통해 성능을 극대화 한다.
주의점
- 동기화 문제로 인해 잘못된 데이터나 교착상태가 발생할 수 있다.
- Thread 가 많아질수록 오버헤드가 증가하고, 시스템 성능이 저하될 수 있다.
'Programming > Java' 카테고리의 다른 글
Java Reflection API에 대하여 (0) | 2024.11.11 |
---|---|
JAVA Edge 브라우저 열기 (0) | 2024.11.08 |
JAVA 파일 수동 COMPILE (0) | 2024.10.30 |
JAVA Garbage Collection(GC) 성능 최적화 (2) | 2024.10.08 |
사업자번호의 유효성 검사 (0) | 2024.09.25 |