프로그램 : 파일들의 집합
프로세스 : 메모리 상에 로딩된 프로그램
멀티 프로세스 : 동일 프로그램 메모리에 여러 번 로딩하면 여러 개의 프로세스가 동작하는 것.
스레드 : CPU를 사용하는 최소 단위.
CPU와 메모리의 작업 수행 속도 차 발생해서 CPU는 메모리의 프로세스 내부 스레드와 대화함.
· 스레드 동시성
순차적 : 단일 스레드 작업
동시성 : 처리할 작업 수가 CPU의 코어 수보다 적을 때병렬성 : 처리할 작업 수가 CPU의 코어 수보다 많을 때
· 스레드 생성 방법
1. Thread 클래스 상속받아 run() 메서드를 오버라이딩2.① Runnable 인터페이스를 구현한 Runnable 객체를 생성 (run()메서드 사용)② Thread 객체를 생성할 때 생성한 Runnable 객체를 생성자로 전달
※ 한 번 실행된 Thread 객체는 재사용할 수 없다. (다시 생성해야 함)
스레드 생성 방법 1run() : 스레드에서 작업할 내용 작성Thread 클래스 기본 생성자로 객체 생성하고 마지막에 start() 메서드 호출해 실행.
※ run(), start() 메서드들의 차이점
start() : 새로운 스레드 생성/추가를 위한 모든 준비, 새 스레드 위에서 run() 실행시키기run() : 스레드 작업 내용 작성
스레드 생성 방법 2
Runnable 객체 내부엔 start() 메서드가 없기 때문에 start()를 갖고 있는 Thread 객체를 생성해야 한다. 구현한 run() 메서드 자체는 Runnable 객체가 가지고 있어 Thread 객체를 생성할 때 생성자의 매개변수로 넘겨주면 Runnable 객체 내부의 run()으로 대체된다.
스레드 생성 방법 3
익명 이너 클래스 문법 이용해 Runnable 인터페이스 객체를 생성한 이후에 실행한다.
run() 메서드 구현 필요.
- 스레드 속성
Thread 클래스를 직접 정의하고 객체를 생성해 사용할 때 참조변수를 이용해 언제든 스레드 객체 속성을 가져올 수 있다. 하지만 직접 스레드 객체 생성했을 때가 아니거나 객체를 생성할 때 참조 변수를 정의하지 않을 경우 객체를 참조할 수 없게 된다.
스레드 객체가 없을 대 Thread 클래스의 정적 메서드인 currnetThread() 메서드를 이용해 현재 스레드 객체 참조값을 얻어 올 수 있다.
static Thread Thread.currentThread()
· 실행 중인 스레드 갯수 가져오기
static int Thread.activeCount()
스레드 이름 지정 및 가져오기
String setName(String name)
String getName()
이름 지정하지 않으면 컴파일러가 대신 자동으로 부여한다. thread-숫자 형태로 부여됨.
· 스레드 우선 순위
1 : 가장 낮은 순위 값
10 : 가장 높은 순위 값
5 : 우선 순위 지정 안했을 시 기본값
우선 순위는 스레드 동시성에 따라 일정 간격 번갈아 실행되는데 이때 의미가 있다. 우선 순위가 높으면 상대적으로 더 많은 시간을 할당받는다.
스레드 객체 우선순위 정하기
void setPriority(int priority)
우선 순위 가져오기
int getPriority()
- 데몬 스레드
일반적으로 스레드 객체를 실행하면 다른 스레드의 종료 여부 관계없이 자신의 스레드가 종료될 때까지 계속 실행된다. 따라서 무한 반복 스레드라면 해당 프로세스는 영원히 종료되지 않을 것이다.
스레드 : 독립적으로 실행
스레드를 생성해 실행한 주 스레드를 포함해 다른 스레드가 종료되면 남아있는 작업이 있더라도 종료해야 할 때가 있다. 이렇듯 일반 스레드가 모두 종료되면 함께 종료되는 스레드를 데몬 스레드라고 한다.
데몬 스레드 설정
void setDemon(boolean on)
데몬 스레드 설정 확인
boolean isDemon()
※ 데몬 설정은 반드시 스레드 실행 전에 즉, start() 메서드 호출 전에 설정해야 한다. 스레드가 실행되고 나면 데몬 설정을 변경할 수 없다.
- 스레드 동기화
동기화 : 하나의 작업이 완전히 완료 후 다른 작업을 수행하는 것
비동기화 : 하나의 작업 명령 이후 완료 여부와 상관없이 바로 다른 작업 명령을 수행하는 것
· 동기화의 필요성
필드 동시에 접근 시 데이터 손실 등 데이터 변형이 일어날 수 있다.
-> 하나의 자원을 여러 스레드가 공유한다면 동기화 처리가 필요한 것이다.
· 동기화 방법
1. 메서드 동기화
접근지정자 synchronized 리턴타입 메서드명(입력매개변수) {
//동기화 내용
}
2. 블록 동기화
동기화 영역을 필요한 부분에 한정해 적용
synchronized (임의의 객체) {
// 동기화 내용
}
· 동기화 원리
모든 객체는 자신만의 열쇠가 있다.
첫번째로 동기화 블록을 실행하는 스레드가 열쇠를 갖고. 스레드가 등기화 블록 실행 완료 전까지 다른 스레드는 열쇠를 얻을 수 없어 실행이 불가하다. 키가 다르면 메서드를 실행시킬 수 없다. 동일한 키끼리 동기화 진행된다.
- 스레드 상태
스레드 상태값 가져오기
Thread.State getState()
enum : 상수 집합
문자열 상수 : NEW, RUNNABLE, TERMINATED, TIME_WAITING, BLOCKED, WAITING이 저장돼 있음
처음 객체가 생성되면 NEW의 상태를 가지며 start() 메서드로 실행하면 RUNNABLE 상태가 된다
RUNNABLE 상태는 실행과 실행대기를 반복하며 CPU를 다른 스레드들과 나눠 사용한다.
run() 메서드가 종료되면 TERMINATED 상태가 된다.
· TIMED_WAITING
정적 메서드인 Thread.sleep() 또는 인스턴스 메서드 join()이 호출되면 되는 상태
static void Thread.sleep(long millis)
static void join(long millis)
말 그대로 일정 시간동안 일시정지 되는 것인데, 일정 시간이 지나거나 interrupt() 메서드가 호출되면 다시 RUNNABLE 상태가 된다.
※ Thread.sleep(), join() 차이점
Thread.sleep(1000) : 외부에서 interrupt() 메서드가 호출되지 않는 한 1초간 정지상태가 유지된다.
join(1000) : 일시 정지 되는 동안 다른 스레드에 CPU 사용을 넘기는 것이다. 다른 스레드 작업이 일정시간보다 일찍 끝나면 interrupt() 메서드 없어도 RUNNABLE 상태가 된다.
· BLOCKED
동기화 메서드나 동기화 블록을 실행하기 위해 먼저 실행중인 스레드의 실행 완료를 기다리는 상태앞 스레드의 동기화 영역 수행이 완료되면 BLOCKED 상태 스레드는 RUNNABLE 상태가 돼 해당 동기화 영역을 실행한다.
· WAITING
시간 정보가 없는 join() 메서드가 호출되거나 wait() 메서드가 호출될 때 되는 상태
wait()은 Object 클래스로부터 상속받는 메서드
synchronized void join()
void wait()
한없이 일시정지하는 상태일 텐데 어떤 메소드를 통해 RUNNABLE 상태로 돌아올 수 있다.
join() 에서의 일시정지는 TIMED_WAITING 때와 마찬가지로 join()의 대상이 종료되거나 외부에서 interrupt() 메서드 호출 시 RUNNABLE 상태로 돌아감
wait() 에서의 일시정지는 Object 클래스의 notify() 또는 notifyAll() 으로 돌아갈 수 있다
※ wait(), notify(), notifyAll()은 동기화 블록 내에서만 사용할 수 있다
static void Thread.yeild() : 다른 스레드에 딱 한 번 CPU 양보 (RUNNABLE 상태에서)
'JAVA > 공부' 카테고리의 다른 글
자바 Adapter 클래스 (0) | 2022.09.01 |
---|---|
자바 AWT 이벤트 (0) | 2022.09.01 |
예외 처리 (0) | 2022.07.11 |
이너 클래스와 이너 인터페이스 (0) | 2022.07.11 |
자바 제어자-2 (0) | 2022.07.02 |