728x90
스레드란?
- 컴퓨터 프로그램에서 실행되는 작업의 가장 작은 단위
- 보통 하나의 프로그램은 여러 개의 스레드를 가질 수 있으며, 이러한 스레드들은 동시에 실행될 수 있음
- 스레드를 사용하면 프로그램이 여러 작업을 동시에 처리하거나, 여러 작업을 병렬로 실행할 수 있어서 전체적인 성능을 향상시킬 수 있음
- 스레드는 프로세스 안에서 메모리를 공유하므로, 데이터를 효율적으로 공유하고 통신할 수 있음
- 스레드를 사용할 때는 동기화와 관련된 문제에 유의해야 하고, 이를 효과적으로 관리하기 위해 동기화 기술을 활용함
그렇다면 자바에서의 스레드 특징은?
- 멀티스레드 지원: 자바는 멀티스레드 프로그래밍을 지원하며, 여러 스레드를 생성하고 관리할 수 있는 강력한 기능을 제공
- 쓰레드 생성과 관리: 자바에서는 스레드를 생성하기 위해 Thread 클래스를 상속하거나 Runnable 인터페이스를 구현하여 스레드를 정의할 수 있다.
- 스레드 우선순위: 자바는 스레드의 우선순위를 지정할 수 있으며, 높은 우선순위의 스레드가 CPU를 더 많이 할당받도록 할 수 있다.
- 동기화 메커니즘 제공: 자바는 synchronized 키워드를 통해 스레드 간의 동기화를 지원하며, 공유 자원에 대한 접근을 안전하게 제어할 수 있다.
- 스레드 상태 관리: 자바에서는 스레드의 상태를 관리하고, 스레드 간의 상호작용을 제어하기 위한 다양한 메서드를 제공한다.
- 스레드 풀 지원: 자바는 스레드 풀(Thread Pool)을 구현하여 스레드의 생성 및 관리를 효율적으로 수행할 수 있도록 지원한다.
자바 스레드의 생성자, 메소드
1) 생성자
- Thread( ) : 새로운 스레드 객체 할당
- Thread(String name) : 새로운 스레드 객체가 할당되며, 스레드 이름은 name으로 설정됨
- Thread(Runnable target) : Runnable target이 구현된 스레드 객체 할당
- Thread(Runnable target, String name) : Runnable target이 구현된 스레드 객체가 할당되면 스레드 이름은 name으로 설정됨.
2) 메소드
- void run( ) : 스레드의 실행코드가 작성되는 메소드로 사용자는 run() 메소드를 오버라이드 하여 사용해야 합니다.
- void start( ) : 스레드가 시작되도록 요청하는 메소드로 JVM은 해당 스레드의 run() 메소드를 호출합니다.
- void interrupt( ) : 스레드를 중지 시킵니다.
- void join( ) : 이 스레드가 끝날때까지 기다립니다.
- void join(long millis) : 최대 millis 시간동안 이 스레드가 끝날때까지 기다립니다.
- static void sleep(long millis) : millis 시간동안 현재 스레드를 일시중지시킵니다.
- static void yield( ) : 현재 스레드의 실행시간을 다른 스레드에게 양보합니다.
- static Thread currentThread( ) : 현재 실행중인 스레드 객체의 참조값을 반환합니다.
- long getId( ) : 스레드의 Id를 반환합니다.
- String getName( ) : 스레드의 이름을 반환합니다.
- int getPriority( ) : 스레드의 우선순위 값을 반환합니다. (우선순위 범위 : 1 ~ 10)
- Thread.State getState( ) : 스레드의 state 값을 반환합니다.
- ThreadGroup getThreadGroup( ) : 스레드가 속한 스레드 그룹을 반환합니다.
- static boolean interrupted( ) : 현재 스레드의 interrupted 여부를 반환합니다.
- boolean isInterrupted( ) : 이 스레드의 interrupted 여부를 반환합니다.
- boolean isAlive( ) : 이 스레드가 살아있는지 여부를 반환합니다.
- boolean isDaemon( ) : 이 스레드가 데몬 스레드인지 여부를 반환합니다.
- void setDaemon(boolean on) : 이 스레드를 데몬 스레드로 변경합니다.
- void setName(String name) : 이 스레드의 이름을 name으로 변경합니다.
- void setPriority(int newPriority) : 이 스레드의 우선순위를 newPriority로 변경합니다.
- String toString( ) : 이 스레드의 이름, 우선순위, 스레드그룹등의 정보를 담은 문자열을 반환합니다.
cf) static 메소드는 해당 메소드를 호출한 스레드 자신에게 적용된다는 점에 유의해야합니다.
자바에서 스레드 구현 방식은?
Runnable 인터페이스 구현
- Runnable 인터페이스를 구현하는 클래스 정의
- run() 메소드를 오버라이드하여 스레드 코드 작성
- Runnable 객체 생성하기
- Thread 객체 생성하기
- start() 메소드로 스레드 시작하기
Thread 클래스 상속
- Thread 클래스를 상속한 클래스 정의
- run() 메소드를 오버라이드하여 스레드 코드 작성
- 스레드 객체 생성하기
- start() 메소드로 스레드 시작하기
둘 다 Run() 메소드를 오버라이딩하는 방식이다.
보통은 Runnable을 사용하는 것을 권장한다.
자바는 단일 상속만을 지원하므로, 이미 다른 클래스를 상속한 경우 Runnable을 구현하여 쓰레드 기능을 추가할 수 있다.
코드 통해 스레드 특징 익히기
멀티스레드 지원
import java.io.*;
import java.net.*;
public class SimpleWebServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Server is running on port 8080...");
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected: " + clientSocket.getInetAddress());
Thread thread = new Thread(() -> {
try {
handleClientRequest(clientSocket);
} catch (IOException e) {
e.printStackTrace();
}
});
thread.start();
}
}
private static void handleClientRequest(Socket clientSocket) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String request = in.readLine();
System.out.println("Request from client: " + request);
// 웹 서버로부터 간단한 응답을 반환
String response = "HTTP/1.1 200 OK\r\n\r\nHello, World!";
out.write(response);
out.flush();
// 자원 해제
in.close();
out.close();
clientSocket.close();
}
}
쓰레드 생성과 관리
Runnable 객체를 생성하여 구현
public class SimpleThreadExample {
public static void main(String[] args) {
// Runnable 객체 생성
Runnable task1 = () -> {
for (int i = 0; i < 5; i++) {
System.out.println("Task 1: " + i);
try {
Thread.sleep(1000); // 1초 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// Runnable 객체 생성
Runnable task2 = () -> {
for (int i = 0; i < 5; i++) {
System.out.println("Task 2: " + i);
try {
Thread.sleep(1000); // 1초 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 스레드 생성 및 시작
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
thread1.start(); // Task 1 수행 스레드 시작
thread2.start(); // Task 2 수행 스레드 시작
}
}
스레드 우선순위, 동기화 메커니즘 제공
동기화 매커니즘을 이해하는 코드
Synchronized를 통한 Lock 매커니즘 사용
>> 동시에 여러 스레드가 공유 자원에 안전하게 접근할 수 있도록 보장
public class SynchronizationExample {
private static int counter = 0;
public static void main(String[] args) {
// 스레드 객체 생성
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
incrementCounter();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
incrementCounter();
}
});
// 두 스레드 시작
thread1.start();
thread2.start();
// 두 스레드가 종료될 때까지 대기
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 결과 출력
System.out.println("Final counter value: " + counter);
}
// 동기화 메서드를 사용하여 counter를 증가시키는 메서드
private synchronized static void incrementCounter() {
counter++;
}
}
스레드 상태 관리
스레드 상태 관리는 스레드가 생성되어 실행되는 동안 그 상태가 변화하는 것을 관리하는 것을 의미한다. 자바에서는 Thread 클래스의 메서드와 상수를 사용하여 스레드의 상태를 관리할 수 있다.
스레드의 주요 상태는 다음과 같습니다:
- NEW: 스레드 객체가 생성되었지만 아직 start() 메서드가 호출되지 않은 상태입니다.
- RUNNABLE: 스레드가 실행되고 있거나 실행 대기 중인 상태입니다.
- BLOCKED: 스레드가 동기화 블록에 의해 대기하고 있는 상태입니다. 다른 스레드가 해당 블록을 사용 중이기 때문에 접근할 수 없습니다.
- WAITING: 스레드가 다른 스레드에 의해 통지될 때까지 무한정 기다리는 상태입니다. 예를 들어 wait(), join(), LockSupport.park() 등의 메서드 호출에 의해 발생합니다.
- TIMED_WAITING: 스레드가 일정 시간 동안 대기하고 있는 상태입니다. Thread.sleep(), Object.wait(long timeout), join(long millis) 등의 메서드 호출에 의해 발생합니다.
- TERMINATED: 스레드의 실행이 종료된 상태입니다. run() 메서드가 종료되었거나 stop() 메서드가 호출되어 스레드가 종료된 경우에 발생합니다.
스레드의 상태는 Thread 클래스의 getState() 메서드를 통해 얻을 수 있습니다. 또한 스레드의 상태 변화를 관찰하고 처리하기 위해 Thread 클래스의 다양한 메서드들을 사용할 수 있습니다. 예를 들어 wait(), notify(), join() 등의 메서드를 사용하여 스레드의 상태를 관리하고 동기화를 구현할 수 있습니다.
'언어 > Java' 카테고리의 다른 글
[Java] record (0) | 2024.04.12 |
---|---|
[Java] JVM 개요 (0) | 2024.04.11 |
Java static (0) | 2024.04.07 |
[Java] 추상 클래스란? (0) | 2024.04.07 |
Java 객체 속성 설정 관련 공부 (1) | 2024.04.06 |