쓰레드 (Thread)
- 하나의 프로세스 안에서 실제 작업을 수행하는 작업 단위 (작업자)
- 각각 자신만의 작업 공간을 가짐 (Context 영역)
- 코드를 실행할 때 사용하는 main 함수는 '메인 쓰레드'임
- 쓰레드별로 작업 시간이 다를 수 있음
# 프로세스 (Process)
- 프로그램이 실행되면 운영체제로부터 메모리를 할당받아, '프로세스 상태'가 됨
- 메모리를 할당받아 실행되고 있는 프로그램
- 주기억장치에 올라간 상태
- 하나의 프로세스는 여러 개의 쓰레드를 가질 수 있음
Thread의 상태 변화
- 작업을 잠깐 쉬면 'Not Runnable' 상태가 됨
- 작업이 완전히 종료되면 'Dead' 상태가 됨
Thread의 기본 명령어
# 쓰레드에게 작업을 시작하도록 명령
- 쓰레드명.start();
- 작업을 시작하면 쓰레드는 run 메서드 내의 부분을 수행함
# 작업을 끝내면 '시간' 만큼 쉬고 작업을 다시 시작하도록 명령
- Thread.sleep(시간);
- 시간 단위 : 밀리세컨드 (1/1000초)
- 휴식이 진행되는 동안 쓰레드는 'Not Runnable' 상태가 되고, 휴식이 끝나면 다시 'Runnable' 상태가 됨
# 현재 쓰레드의 정보 확인
- System.out.println(Thread.currentThread());
- 출력 : [해당 쓰레드, 우선순위, 그룹명]
기본 문법
# 쓰레드를 생성하는 방법
public class 쓰레드클래스명 extends Thread {
// 멤버변수
// 생성자
// Thread의 run 메서드 오버라이드
@Override
public void run() {
// 작업 내용
...
// 작업을 쉬면서 진행하도록 하려면 sleep 설정
try {
Thread.sleep(시간
} catch (InterruptedException e) {
e.printStackTrace();
}
} // end of run
}
# 쓰레드를 사용하는 방법
public static void main(String[] args) {
// 현재 쓰레드가 누군지 확인
System.out.println(Thread.currentThread());
// 쓰레드 생성
쓰레드클래스 쓰레드명 = new 쓰레드클래스();
// 쓰레드에게 작업을 시작시킴
쓰레드명.start();
} // end of main
Thread 클래스를 상속받지 못하는 경우
- 다른 클래스를 상속받고 있다면, 다중 상속을 할 수 없기 때문에 쓰레드를 상속받을 수 없음
→ Runnable 인터페이스를 구현해서 사용함 or 익명 구현 클래스로 사용함
# 쓰레드를 생성하는 방법
class SubWorker extends 타클래스 implements Runnable {
// run 메서드 오버라이드
@Override
public void run() {
// 실행할 코드
}
}
------------------------------
// 또는 익명 구현 클래스 + 람다 표현식
new Thread(() -> {
// run 메서드 안에 들어갈 실행 코드
}).start();
# 쓰레드를 사용하는 방법
public static void main(String[] args) {
// 쓰레드 생성
SubWorker subWorker = new SubWorker();
// start 메서드는 Thread가 가지고 있음
// Thread의 생성자 중에서는 Runnable 타입을 매개변수로 받는 것이 있음
// 다형성을 통해, subWorker는 Runnable 타입으로도 볼 수 있음
Thread 쓰레드1 = new Thread(subWorker);
Thread 쓰레드2 = new Thread(subWorker);
// 시작 시점은 자유롭게 설정할 수 있음 (이벤트, 연산 이후, ...)
쓰레드1.start();
쓰레드2.start();
} // end of main
멀티 쓰레딩 (Multi threading)
- 여러 쓰레드가 수행되는 프로그래밍 환경
- 여러 작업이 동시에 실행되는 효과
: 작업자들의 실행 순서를 개발자가 완벽히 제어할 수는 없음
# 멀티 쓰레딩 환경에서 발생할 수 있는 문제점
- 두 개의 쓰레드가 같은 객체에 동시에 접근할 경우 오류가 발생할 가능성이 있음
- 임계영역 (Critical section)
: 여러 쓰레드가 공유하는 자원 중에서 경쟁이 발생하는 부분
- Race condition
: 여러 쓰레드가 공유하는 자원에 대한 작업을 수행할 때, 서로 자원을 차지하려는 상황
동기화 (Synchoronization)
- 임계영역에 접근한 경우, 공유 자원을 lock해서 한 쓰레드가 작업을 수행하는 동안에는
다른 쓰레드의 접근을 제어함으로써, 오류를 방지함
- 일종의 순차적 수행
- 예제 :
# 방법 1 : synchronized 메서드
// 메서드 선언부
접근제어자 synchronized 반환자료형 메서드명(매개변수) {
...
# 방법 2 : synchronized 블록
메서드 선언부 {
synchronized (this) {
// 실행할 코드
}
}
'Java > Base' 카테고리의 다른 글
[Java] 자료 구조 (0) | 2023.02.21 |
---|---|
[Java] Thread - 은행 계좌 입출금에 대한 동기화 기능 구현 (0) | 2023.02.19 |
[Java] 제네릭 (Generic) (0) | 2023.02.17 |
[Java] 내부 클래스와 익명 클래스 (1) | 2023.02.16 |
[Java] 오류와 예외 처리 (0) | 2023.02.15 |