Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- greedy
- 구현
- Class
- java
- Binary Search
- Stack
- geometry
- Matrix
- SQL
- simulation
- 자바
- database
- 코테
- sorting
- Binary Tree
- array
- Data Structure
- 코딩테스트
- 파이썬
- Tree
- implement
- Method
- bit manipulation
- two pointers
- string
- Math
- Counting
- Number Theory
- dynamic programming
- hash table
Archives
- Today
- Total
코린이의 소소한 공부노트
쓰레드의 구현 방법과 실행 본문
[쓰레드의 구현 방법]
아래 두 가지 방법 중 하나를 선택한 후 run()에 쓰레드로 작업하고자 하는 내용을 채운다.
1. Thread 클래스를 상속받는다.
class MyThread1 extends Thread{
public void run(){ // Thread 클래스의 run() 오버라이딩
for(int i=0; i < 5; i++)
System.out.println(getName());
// 조상인 Thread의 getName()을 호출
// this.getName()에서 this가 생략된 형태
}
}
2. Runnable 인터페이스를 구현한다. (권장. 자바는 단일 상속)
public interface Runnable{
public abstract void run();
}
class MyThread2 implements Runnable{
public void run() { // Runnable 인터페이스의 추상 메서드 run() 구현
for(int i=0; i < 5; i++)
// 인터페이스를 구현한 것이기 때문에 getName에 다음과 같이 접근한다.
// Thread.currentThread() - 현재 실행중인 Thread를 반환한다.
System.out.println(Thread.currentThread().getName());
}
}
[쓰레드의 실행]
// 쓰레드 생성
// 1. Thread 클래스를 상속받은 경우
MyThread1 t1 = new MyThread1();
// 2. Runnable 인터페이스를 구현한 경우
Runnable r = new MyThread2();
Thread t2 = new Thread(r); // 생성자 Thread(Runnable target)
// 위 두줄의 코드를 한 줄로 줄이면 다음과 같다.
// Thread t2 = new Thread(new MyThread2());
t1.start(); // 쓰레드 실행
t2.start();
// 결과
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0 // 여기까지가 t1.start()의 결과
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1 // 여기까지가 t2.start()의 결과
- 위의 예시에서 반복 횟수를 늘린 멀티 쓰레드 실행
class ThreadEx1_1 extends Thread { // Thread 클래스 상속
public void run() {
for(int i=0; i < 100; i++)
System.out.print(0);
}
}
class ThreadEx1_2 implements Runnable { // Runnable 인터페이스 구현
public void run() {
for(int i=0; i < 100 ; i++)
System.out.print(1);
}
}
// main()
ThreadEx1_1 t1 = new ThreadEx1_1();
Runnable r = new ThreadEx1_2();
Thread t2 = new Thread(r);
t1.start();
t2.start();
// 결과
0000001111...00000111111000000001111
// 0과 1이 번갈아가면서 100개씩 출력된다
// t1과 t2중 무엇이 먼저 시작될지는 OS스케줄러가 결정한다.
- run()의 작업들을 전부 main()으로 옮겨서 싱글 쓰레드로 실행
for(int i=0; i < 100; i++)
System.out.print(0);
for(int i=0; i < 100 ; i++)
System.out.print(1);
// 결과
0000...0000011111...1111111
// 0이 100개 먼저 출력되고 1이 100개 출력된다.
[실행 메서드 - start(), run()]
1. 쓰레드를 생성한 후 start()를 호출해야 쓰레드가 작업을 시작한다.
- start()를 실행한다고 바로 실행되는 것이 아니라, 실행 가능 상태로 되는 것뿐이다.
- OS스케줄러가 실행 순서를 결정하고, 실행 시간도 결정한다.
TereadEx1_1 t1 = new TereadEx1_1(); // 쓰레드 t1 생성
TereadEx1_1 t2 = new TereadEx1_1(); // 쓰레드 t2 생성
t1.start(); // 쓰레드 t1 실행
t2.start(); // 쓰레드 t2 실행
// t1, t2 중 어느 것이 먼저 실행될지 모른다.
2. start()를 호출한 후 run()을 호출해야 독립적인 수행(쓰레드 실행)이 가능해진다.
[쿠키글] main 쓰레드
1. main()의 코드를 수행하는 쓰레드
- 위의 그림에서 첫 번째 호출 스택을 main 쓰레드로 봐도 좋다.
2. 쓰레드는 ‘사용자 쓰레드’와 ‘데몬 쓰레드(보조 쓰레드)’ 두 종류가 있다.
3. 실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다.
- 위 그림에서 main 쓰레드가 종료돼도 run 쓰레드가 살아있다면 프로그램은 종료되지 않는다.
예시를 통해 main 쓰레드의 실행 종료와 프로그램 종료의 차이를 살펴보자.
// ThreadEx1 클래스의 run()
for(int i=0; i < 30; i++) {
System.out.print(0);
// ThreadEx2 클래스의 run()
for(int i=0; i < 30; i++) {
System.out.print(1);
// 3-1) main()에서 쓰레드를 그냥 실행시킨 경우
long startTime = 0;
ThreadEx1 th1 = new ThreadEx1();
ThreadEx2 th2 = new ThreadEx2();
th1.start();
th2.start();
startTime = System.currentTimeMillis();
System.out.print("소요시간:" + (System.currentTimeMillis() - startTime));
// 결과
소요시간:01110000000000000000000011111111111111111
-> main() 종료 -> t1 실행 종료 -> t2 실행 종료 -> 프로그램 종료
// 3-2) main()에서 쓰레드 종료를 기다리게 한 경우
long startTime = 0;
ThreadEx1 th1 = new ThreadEx1();
ThreadEx2 th2 = new ThreadEx2();
th1.start();
th2.start();
try {
th1.join(); // main쓰레드가 th1의 작업이 끝날 때까지 기다린다.
th2.join(); // main쓰레드가 th2의 작업이 끝날 때까지 기다린다.
} catch(InterruptedException e) {}
startTime = System.currentTimeMillis();
System.out.print("소요시간:" + (System.currentTimeMillis() - startTime));
// 결과
1111111111100111111111000000000000000000소요시간:3
-> t2 실행 종료 -> t1 실행 종료 -> main() 종료 -> 프로그램 종료
'Java' 카테고리의 다른 글
쓰레드의 우선순위와 그룹 (0) | 2022.11.30 |
---|---|
싱글쓰레드와 멀티쓰레드의 실행 (0) | 2022.11.30 |
쓰레드의 정의 (0) | 2022.11.24 |
애너테이션 만들기 (0) | 2022.11.21 |
애너테이션의 정의와 종류 (0) | 2022.11.17 |