hyeonga_code
Java의 신2_Chapter 7_Thread 본문
2024.04.02
- 스레드_Thread
-- 하나의 프로세스 내에서 여러 스레드는 수행될 수 있으나 여러 프로세스가 하나의 스레드를 수행할 수는 없다.
-- 경량 프로세스_Lightweight Process
-- WAS_Web Application Server
---- 자바를 사용한 웹을 제공
---- main()메소드에서 생성한 스레드가 수행되는 것
-- 스레드 생성 방법
1) Runnable 인터페이스
---- 구현된 메소드
2) Thread 클래스(선호)
---- Runnable 인터페이스를 구현한 클래스
void run()
// 스레드가 시작하면 수행
---- 예제
package e.thread;
public class RunnableSample implements Runnable {
public void run() {
System.out.println("Runnable run()");
} //end run()
} //end class(RunnableSample)
public class ThreadSample extends Thread {
public void run() {
System.out.println("Thread run()");
} //end run()
} //end class(ThreadSample)
public class RunThread {
public static void main(String[] args) {
RunThreads threads = new RunThreads();
threads.runBasic();
} //end main()
public void runBasic() {
RunnableSample runnable = new RunnableSample();
new Thread(runnable).start();
ThreadSample thread = new ThreadSample();
thread.start();
System.out.println("End");
} //end runBasic()
} //end class(RunThread)
---- 구현해야 하는 스레드가 수행되는 메소드는 run()
---- 스레드를 실행시키는 메소드는 start()
---- RunnableSample 클래스는 Thread 클래스의 생성자에 해당 객체를 추가한 뒤 시작해야 한다.
---- Runnable 인터페이스가 필요한 이유
------ 확장은 하나의 클래스만 가능하다. 확장한 상위 클래스가 스레드를 확장하지 않은 경우, 인터페이스를 구현해서 스레드로 구현할 수 있다.
>>> 결과
// 1.
Runnable run()
Thread run()
End
// 2.
Runnable run()
End
Thread run()
---- start()를 통해 시작하는 것은 프로세스가 아닌 하나의 스레드를 JVM에 추가하여 실행하는 것
---- 스레드에 존재하는 메소드와 별개로 다음 코드를 실행한다.
-- 생성자
Thread()
// 새로운 스레드 생성
Thread(Runnable target)
// target 객체의 run() 메소드를 수행하는 스레드 생성
Thread(Runnable target, String name)
// target 객체의 run() 메소드를 수행하고, 이름을 name으로 지정
Thread(String name)
// 이름이 name인 스레드 생성
Thread(ThreadGroup group, Runnable target)
// group에 속하는 target 객체의 run() 메소드를 수행하는 스레드 생성
Thread(ThreadGroup group, Runnable target, String name)
// group에 속하는 target 객체의 run() 메소드를 수행하고, 이름을 name으로 지정
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
// group에 속하는 target 객체의 run() 메소드를 수행하고, 이름을 name을 가진 stackSize 크기의 스레드 생성
Thread(ThreadGroup group, String name)
// group에 속하는 이름이 name인 스레드 생성
---- 모든 스레드는 이름이 있다.
------ 이름을 따로 지정하지 않는 경우 Thread-n(생성순서)
---- 스레드의 이름이 중복되어도 예외/오류가 발생하지 않는다.
---- 스레드 생성 시 묶어 놓을 수 있다. > ThreadGroup
---- stackSize 의 스택은 Collection의 Stack과 무관하다.
------ 자바 프로세스가 시작되면 실행 데이터 공간이 구성되는데 그 중 하나의 공간이다.
------ 스레드가 생성될 때마다 별도의 스택이 할당된다.
---- 스레드 객체 생성 시 매개변수를 넘겨 인스턴스 변수로 사용할 수 있다.
-- sleep()
static void sleep(long millis)
static void sleep(long millis, int nanos)
---- 항상 try-catch 블록으로 묶어야 한다.
------ InterruptedException 예외가 발생할 수 있기 때문이다. (Exception)
-- 메소드
void run()
// 구현해야 하는 메소드
long getId()
// 고유 ID를 리턴(JVM에서 자동 생성)
String getName()
// 스레드의 이름을 리턴
void setName(String name)
// 스레드의 이름을 지정
int getPriority()
// 스레드 우선순위를 확인
void setPriority(int newPriority)
// 스레드 우선순위를 지정
boolean isDaemon()
// 데몬인지 확인
void setDaemon(boolean on)
// 데몬으로 설정하는지의 여부
StackTraceElement[] getStackTrace()
// 스레드의 스택 정보를 확인
Thread.State getState()
// 스레드의 상태 확인
ThreadGroup getThreadGroup()
// 스레드의 그룹 확인
---- 스레드의 우선순위
------ 대기하고 있는 상황에서 더 먼저 수행하는 순위
------ 기본값을 사용하는 것이 일반적이다.(기본값: 5)
---- 우선순위와 관계 있는 상수
MAX_PRIORITY
// 가장 높은 우선순위 [10]
NORM_PRIORITY
// 일반 스레드의 우선순위 [5]
MIN_PRIORITY
// 가장 낮은 우선순위 [1]
-- 데몬 스레드_DaemonThread
---- 스레드를 수행하기 전에 지정해야 인식한다.
---- 데몬 스레드를 제외한 스레드는 JVM이 해당 스레드가 끝날 때까지 기다린다.
---- 데몬 스레드가 수행되는 중에도 JVM이 종료될 수 있다.
---- 모니터링과 같은 부가적인 작업을 수행하는 스레드를 선언할 때 사용한다.
-- Synchronized
---- 클래스나 메소드가 스레드에 안전하기 위해서는 synchronized를 사용해야 한다.
---- 앞서 실행하던 스레드가 종료될 때까지 대기한다.
------ 같은 객체를 참조할 때에만 유효하다.
---- 여러 스레드에서 하나의 객체에 있는 인스턴스 변수를 동시에 처리할 때 발생할 수 있는 문제를 해결하기 위해 필요한 것이다.
------ 메소드에서 인스턴스 변수를 수정하려고 할 때 동시에 연산을 수행하여 값이 꼬이는 상황이 발생할 수 있다.
---- 선언 방법
1) 메소드를 선언_ synchronized methods
2) 메소드 내의 특정 문장만 선언_ synchronized statements
Object lock = new Object();
public void plus(int value) {
synchronized(lock) {
amount += value;
}
} //end plus()
---- StringBuffer vs StringBuilder
-- StringBuffer
---- 스레드에 안전하다.
---- 주요 데이터 처리부분을 synchronized로 감싸두었다.
---- 하나의 문자열 객체를 여러 스레드에서 공유해야 하는 경우 사용한다.
-- StringBuilder
---- 여러 스레드에서 공유할 일이 없는 경우 사용한다.
-- 스레드를 통제하는 메소드
Thread.State getState()
// 스레드의 상태 확인
void join()
// 수행중인 스레드가 중지될 때까지 대기
void join(long millis)
void join(long millis, int nanos)
// 지정 시간만큼 대기
void interrupt()
// 수행중인 스레드에 중지 요청
---- interrupt() 메소드는 InterruptedException 예외를 발생시키면서 종료된다.
-- Thread의 State enum Class
NEW // 스레드가 생성되었으나 시작되지는 않은 상태
RUNNABLE // 스레드가 실행중인 상태
BLOCKED // 스레드가 실행 중지인 상태, 모디터 락이 풀리기 기다리는 상태
WAITING // 스레드가 대기중인 상태
TIMED_WAITING // 특정 시간 만큼 스레드가 대기중인 상태
TERMINATED // 스레드가 종료된 상태
---- static으로 선언되어 있다. (Thread.State.NEW)
---- NEW > 상태 > TERMINATED 의 사이클을 가진다.
-- 상태 확인을 위한 메소드
void checkAccess()
// 현재 수행중인 스레드가 해당 스레드를 수정할 권한이 있는지 확인
// 없는 경우 SecurityException 예외 발생
boolean isAlive()
// 스레드가 살아있는지 확인(run()메소드의 종료여부)
boolean isInterrupted()
// run() 메소드가 정상적으로 종료되지 않고 interrupted() 메소드 호출로 종료되었는지 확인
static boolean interrupted()
// 현재 스레드가 종료되었는지 확인
-- 주요 메소드
static int activeCount()
// 현재 스레드가 속한 스레드 그룹의 스레드 중 살아있는 스레드 개수를 리턴
static Thread currentThread()
// 현재 수행중인 스레드의 객체를 리턴
static void dumpStack()
// 콘솔 창에 현재 스레드의 스택 정보를 출력
-- 스레드 상태를 통제하는 Object 클래스 메소드
void wait()
// 다른 스레드가 Object 객체에 대한 notify() 메소드나 notifyAll() 메소드를 호출할 때까지 대기
void wait(long timeout)
// 지정 시간만큼 대기 후 실행(1/1,000초 > 1초(1000))
void wait(long timeout, int nanos)
// 지정 시간만큼 대기 후 실행(1/1,000,000,000초)
void notify()
// Object 객체의 모니터에 대기하고 있는 단일 스레드를 깨운다.
void notifyAll()
// Object 객체의 모니터에 대기하고 있는 모든 스레드를 깨운다.
---- notify() 메소드 호출 시 먼저 대기하고 있는 것부터 상태를 풀어준다.
-- ThreadGroup의 메소드
int activeCount()
// 실행중인 스레드의 개수를 리턴
int activeGroupCount()
// 실행중인 스레드 그룹의 개수를 리턴
int enumerate(Thread[] list)
// 현재 스레드그룹에 있는 모든 스레드를 매개변수로 넘어온 스레드 배열에 담는다.
int enumerate(Thread[] list, boolean recures)
// 현재 스레드그룹의 모든 스레드를 배열에 담고, true인 경우 하위의 스레드 그룹 목록도 포함
int enumerate(ThreadGroup[] list)
// 현재 스레드그룹의 모든 스레드 그룹을 배열에 담는다.
int enumerate(ThreadGroup[] list, boolean recurse)
// 현재 스레드그룹에 있는 모든 스레드그룹을 배열에 담고 true인경우 하위의 스레드 그룹도 포함
String getName()
// 스레드그룹의 이름을 리턴
ThreadGroup getParent()
// 부모 스레드그룹을 리턴
void list()
// 스레드그룹의 상세 정보를 출력
void setDaemon(boolean daemon)
// 현재 스레드 그룹에 속한 스레드들을 데몬스레드로 지정
---- enumerate() 메소드는 배열에 저장되는 스레드의 개수를 리턴한다.
------ activeCount() 메소드로 현재 실행중인 메소드의 개수를 파악한 후 배열을 생성하는 것이 효율적이다.
'Java' 카테고리의 다른 글
Java의 신2_Chapter 8_I/O (0) | 2024.04.03 |
---|---|
Java의 신2_Chapter 6_Collection Map (0) | 2024.04.03 |
Java의 신2_Chapter 5_Collection Set Queue (0) | 2024.04.02 |
Java의 신2_Chapter 4_Collection List (0) | 2024.04.02 |
Java의 신2_Chapter 3_Generic (0) | 2024.04.02 |