hyeonga_code

Java의 신2_Chapter 7_Thread 본문

Java

Java의 신2_Chapter 7_Thread

hyeonga 2024. 4. 3. 06:59
반응형

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