[Java] 스레드 이해
2022. 10. 21. 14:40ㆍTIL💡/Java
Java에서 Thread를 구현하는 방법은 크게 두 가지가 있다.
1. Thread class 상속 → 다른 클래스 상속이 불가하니 2번 선호
2. Runnable 인터페이스 구현
public class ThreadBasic {
public static void main(String[] args) {
// 1. Thread Class를 상속받는 방법
Thread t1 = new MyThread1(); // 쓰레드의 생성
t1.start(); // 쓰레드의 실행. run()이 종료되면 MyThread1 소멸된다.
// 2. Runnable 인터페이스를 구현하는 방법
Thread t2 = new Thread(new MyThread2());
t2.start(); // 쓰레드의 실행. run()이 종료되면 MyThread2 소멸된다.
}
}
// 1. Thread Class를 상속받는 방법
class MyThread1 extends Thread {
@Override
public void run() {
//작업할 내용
}
}
// 2. Runnable 인터페이스를 구현하는 방법
class MyThread2 implements Runnable {
@Override
public void run() {
//작업할 내용
}
}
Runnable 인터페이스를 구현하는 게 일반적인 방법이다.
Runnable 인터페이스는 run()만 정의되어 있는 간단한 인터페이스이다.
Runnable 인터페이스를 구현한 경우, Runnable 인터페이스를 구현한 클래스의 인스턴스를 생성한 다음, 이 인스턴스를 Thread 클래스 생성자의 매개변수로 제공한다.
Thread를 생성했다고 해서 자동으로 실행되는 것은 아니다.
start() 메소드를 호출해야만 Thread가 실행된다.
Thread 동작 시 run()이 자동적으로 호출된다.
main 메소드의 작업을 수행하는 것도 Thread이며, 이를 main 쓰레드라고 한다.
public class ThreadEX1 {
static long startTime = 0;
public static void main(String[] args) { // ==> main 메소드의 코드를 수행하는 쓰레드
// 모든 프로세스(실행중인 프로그램)는 최소한 하나의 쓰레드(프로세스 내에서 실제 작업을 수행)를 갖고 있다.
// 대부분의 프로그램이 멀티쓰레드로 작성되어 있다.
// 멀티쓰레드 장점 : 1. 시스템 자원의 효율적 사용
// 2. 사용자에 대한 응답성 향상(채팅 중에 파일 전송)
// 3. 작업이 분리되어 코드가 간결해진다.
// 멀티쓰레드 단점 : 1. 동기화에 주의해야 한다. 2. 교착상태가 발생하지 않도록 해야 한다.
// 3. 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다.
// 쓰레드를 생성한 후에 start()를 호출해야 쓰레드가 작업을 시작한다.
ThreadEx1_A t1 = new ThreadEx1_A(); // 쓰레드의 생성
Runnable r = new ThreadEx1_B();
Thread t2 = new Thread(r);
t1.start(); // 쓰레드 t1을 실행시킨다. ==> 새로운 호출스택 생성
t2.start(); // 쓰레드 t2를 실행시킨다. ==> 새로운 호출스택 생성
// 쓰레드는 순차적으로 실행되지 않고 섞여서 실행된다.
// 실행순서는 OS 스케줄러가 결정한다.
// 쓰레드는 '사용자 쓰레드' 와 '데몬 쓰레드' 두 종류가 있다.
// 실행중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다.
startTime = System.currentTimeMillis();
try {
t1.join(); // main쓰레드가 t1의 작업이 끝날 때까지 기다린다.
t2.join(); // main쓰레드가 t2의 작업이 끝날 때까지 기다린다.
} catch(InterruptedException e) {}
System.out.print("소요시간:" + (System.currentTimeMillis() - ThreadEX1.startTime));
}
}
class ThreadEx1_A extends Thread { // 1. 쓰레드 Class 상속
public void run() { // Thread 클래스의 run()을 오버라이딩
for(int i=0; i < 300; i++) {
//System.out.println(getName()); // 조상인 Thread의 getName()을 호출
System.out.print(new String("-"));
}
}
}
class ThreadEx1_B implements Runnable { // 2. Runnable 인터페이스 구현
public void run() { // Runnable 인터페이스의 추상메소드 run()을 구현
// run() : 쓰레드가 수행할 작업을 작성
for(int i=0; i < 300; i++) {
// Thread.currentThread() - 현재 실행중인 Thread를 반환한다.
//System.out.println(Thread.currentThread().getName());
System.out.print(new String("|"));
}
}
}
main thread
- 모든 자바 프로그램은 메인 쓰레드가 main() 메소드가 실행하면서 시작한다.
- return을 만나면 실행을 종료한다.
- main thread는 작업 쓰레드를 만들어서 병렬로 코드를 실행할 수 있다.
- 작업 쓰레드를 만들려면, Thread 클래스를 상속하거나 Runnable 인터페이스를 구현한다.
- 멀티 쓰레드는 실행 중인 쓰레드가 하나라도 있다면, 프로세스는 종료되지 않는다.
- 멀티 쓰레드 작업 시에는 각 쓰레드끼리 정보를 주고받을 수 있다.(프로세스끼리는 정보를 주고 받을 수 없다.)
daemon thread
- 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행한다.
- 일반 쓰레드가 모두 종료되면 자동적으로 종료된다.
- 가비지 컬렉터, 자동 저장, 화면 자동 갱신 등에 사용된다.
- 무한 루프와 조건문을 이용해서 실행 후 대기하다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.
- setDaemon(boolean on)은 반드시 start()를 호출하기 전에 실행되어야 한다.
참고
https://link2me.tistory.com/1730
'TIL💡 > Java' 카테고리의 다른 글
Spring 학습 자료 링크 (0) | 2022.11.14 |
---|---|
[Java] String, StringBuffer, StringBuilder (0) | 2022.10.22 |
[Java] 스레드 생명 주기 상태 (0) | 2022.10.21 |
[Java] 자바 동시성(멀티스레딩)의 개요 (0) | 2022.10.21 |
스프링 컨테이너(Container)와 스프링 빈(Bean) (0) | 2022.06.16 |