스레드 Thread
- 운영 체제를 배웠다면 스레드의 개념은 익히 알 것이다.
- 스레드는 프로그램 수행의 가장 작은 단위를 의미한다.
- 스레드는 한 가지 일을 하는 프로세스의 단점을 극복하고자 여러 가지 일을 동시에 하기 위해 탄생했다.
- 스레드는 다음과 같은 생성 주기를 갖는다.
자바의 스레드 모델과 버전 별 변경점
자바의 스레드 모델은 자바에서 동시성(Concurrency)를 구현하기 위해 탄생했다.
- JAVA 1.0 - 초기 버전에서는 기본적인 동작을 하는
Thread
클래스가 존재했다. - JAVA 1.2 -
synchronized
키워드를 통한 동기화 기능과wait()
,notify()
,notifyAll()
****메서드를 통해 스레드를 제어할 수 있게 되었다. - JAVA 5 -
java.util.concurrent
패키지가 도입되었고,Callable
과Future
및Executor
,ExecutorService
,Executors
등등 스레드 풀, 동시성 컬렉션 등 동시성 기능들이 대거 추가되었다. - JAVA 7 -
Fork / Join Framework
추가로 병렬 프로그래밍에 대한 기능을 추가했다. - JAVA 8 -
CompletableFuture
클래스를 통해 비동기 처리를 더욱 쉽게 다룰 수 있게 되었다. 이는 자바 5에서 추가된Future의
단점들을 극복한 클래스라고 한다.
자바 스레드 동작 과정
MyThread.java
public class MyThread implements Runnable {
public MyThread() {
}
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
먼저 스레드를 사용하기 위해서는 Runnable
클래스를 상속받아 사용한다.
Thread
클래스를 상속받게 되면, 다중 상속을 받을 수 없어 Runnable
클래스를 상속 받는 것이 권장된다.
run() 메서드에는 실제 작업 내용을 구현해 주면 된다.
작업 내용에 적힌 Thread.currentThread().getName()
코드는 현재 스레드의 이름을 출력한다.
ThreadMain.java
public class ThreadMain {
public static void main(String[] args) {
Thread thread = new Thread(new MyThread());
thread.start();
}
}
실제로 스레드를 생성하고 사용해 동작을 살펴보자.
상속받아 구현한 MyThread
를 생성자에 넣고, start()
메서드를 통해 스레드를 생성해 줄 수 있다.
// ********Thread-0
다음과 같은 실행 결과가 나온다.
그렇다면 thread.run()을
통해 직접 실행한 것과 무엇이 다를까?
public class ThreadMain {
public static void main(String[] args) {
Thread thread = new Thread(new MyThread());
thread.run();
}
}
다음과 같이 코드를 변경한 뒤 실행해 보았다.
// main
main에서 실행되었다.
위 사진을 참고하면 이해하기 쉬울 것 같다.
start()
메서드는 스레드를 생성한 뒤 그 스레드의 호출 스택에 run()
메서드를 넣는다.
하지만 run()
메서드를 직접 사용하게 되면 다른 스레드를 생성하지 않는다.
생성된 스레드는 OS의 스케쥴러에 따라 호출되어 실행된다.
public class ThreadMain {
public static void main(String[] args) {
Thread thread0 = new Thread(new MyThread());
Thread thread1 = new Thread(new MyThread());
thread0.start();
thread1.start();
}
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.print(Thread.currentThread().getName() + " ");
}
}
// Thread-1 Thread-1 Thread-1 Thread-1 Thread-1
// Thread-0 Thread-1 Thread-0 Thread-1 Thread-0
// Thread-1 Thread-0 Thread-1 Thread-0 Thread-1
// Thread-0 Thread-0 Thread-0 Thread-0 Thread-0
다음과 같이 코드를 변경해 실행해 보면 스레드 0을 먼저 만들었음에도 스레드 1 이 먼저 수행된다.
또한 스레드의 작업 내용이 모두 수행된 뒤 다른 스레드의 동작이 수행되는 것이 아닌, 중간에 순서가 엉켜있는 것을 알 수 있다.
이를 통해 스레드가 동작하도록 구현함을 알 수 있다.
앞서 설명했던 스레드의 동작주기와 엮어 생각해 본다면 순서가 엉켜있다는 사실이 당연한 결과임을 알 수 있다!
[참고 자료]
'Study > Java' 카테고리의 다른 글
[Java] 불변 객체 (Immutable Object) 란? (0) | 2023.07.23 |
---|---|
[JUnit] 다양한 Assertions 사용하기 (1) | 2023.07.11 |
[JAVA] 동일성, 동등성 그리고 equals, hashcode 재정의 (0) | 2023.07.09 |
[Java] 코딩테스트에 자주 쓰는 문법 정리 (0) | 2022.09.29 |
[Java / IntelliJ] 인텔리제이 입출력 txt로 받기 (0) | 2022.09.29 |