- Java에서 스레드는 ‘멀티 스레드(Multi-Thread)’을 지원하여 하나의 프로세스 안에 한 개 이상의 스레드를 지원하는 구조입니다.
- Java에서는 멀티 스레드를 통해 ‘비동기식 및 병렬 애플리케이션’을 개발할 수 있습니다
[ 더 알아보기 ]
💡 비동기식 및 병렬 애플리케이션이란?
- 애플리케이션이 실행 중인 동안 사용자가 다른 작업을 수행할 수 있도록 합니다. 웹 브라우저에서는 웹 페이지를 로드하는 동안 사용자가 다른 작업을 수행할 수 있습니다. 예를 들어, 이메일을 보내는 애플리케이션은 이메일을 보내는 작업과 동시에 사용자의 이메일을 읽는 작업을 수행할 수 있습니다. 💡 블로킹 (blocking I/O)란?
- I/O가 동작되고 있는 동안에 다른 일을 처리하지 못하는 상태를 의미하며 함수가 모든 일을 마무리될 때까지 다음 처리가 안되는 것을 의미합니다. 💡 논 블로킹(Non-blocking I/O)란?
- I/O가 동작을 하면서 request를 받으면 바로 다음 처리에 요청을 보내 놓고 다른 작업을 처리하다가 먼저 요청한 작업이 끝나면 이벤트를 받아서 응답을 보내는 것을 의미합니다.
- 함수 호출 시 생성되는 ‘지역 변수와 매개변수’가 저장되며 함수가 호출되었을 때 임시로 저장되고 ‘함수의 호출이 끝나면 해당 영역의 메모리에서 해제’가 되는 영역을 의미합니다.
- 이 영역은 Thread 마다 독립적으로 존재하며 Thread 간에 공유되지 않습니다. 따라서, 스택 영역에서는 동기화 문제가 발생하지 않습니다.
[ 더 알아보기 ] 💡 Java에서 스레드 동기화 문제란?
- 스레드는 프로그램이 동시에 여러 작업을 수행할 수 있도록 해주는 기능입니다. 하지만 ‘여러 스레드가 동시에 하나의 자원에 접근하면서 발생하는 문제’가 동기화 문제입니다.
- 스레드는 실행되는 시간이 OS에 의해 관리되기 때문에 어떤 스레드가 먼저 실행될지 예측할 수 없습니다. 따라서 여러 스레드가 동시에 하나의 자원에 접근하면, 결과가 예측할 수 없게 됩니다. 또한, 스레드가 자원에 접근하는 순서에 따라서는 원하는 결과를 얻을 수 없는 경우도 있습니다.
- 하나의 프로세스 내에서 하나의 스레드만 실행되는 것을 말합니다(순차 실행). 프로그램이 하나의 작업만 처리할 수 있다는 의미이며, 다른 작업이 실행되기 전에 현재 작업이 완료되어야 합니다.
- 멀티 태스킹을 지원하지 않고 하나의 태스크만 처리할 수 있으므로 처리량이 낮아지는 단점이 있습니다.
💡 멀티 스레드(Multi Thread) 란?
- 하나의 프로세스 내에서 동시에 여러 개의 스레드가 실행되는 것을 말합니다(병행 실행). 스레드가 동시에 여러 작업을 처리할 수 있기 때문에 시스템의 성능을 향상할 수 있습니다.
- 프로그램의 작업을 분할하여 처리하기 때문에 다양한 작업을 동시에 처리하여 빠르고 효율적으로 실행할 수 있습니다. 그러나 스레드 간의 동기화 같은 부작용으로 이를 고려하여 프로그래밍해야 합니다.
[ 더 알아보기 ] 💡 순차실행(Sequential Execution)이란?
- 스레드의 순차실행은 각 스레드가 순서대로 실행되는 것을 의미합니다. - 하나의 스레드가 실행 중이면, 다른 스레드는 대기 상태에 있습니다. 순차실행은 여러 스레드가 동시에 처리해야 하는 작업을 처리하기에는 적합하지 않습니다.
💡 병행실행(Concurrency Execution)
- 스레드의 병행 실행은 여러 개의 스레드가 동시에 실행되는 것을 의미합니다. 각 스레드는 서로 독립적으로 실행되기 때문에, 여러 개의 스레드가 협력하여 하나의 작업을 처리할 수 있습니다. 병행 실행은 여러 작업을 동시에 처리해야 하는 경우에 적합합니다.
💡 단일 스레드보다 멀티스레드가 당연히 좋은 것 아닌가?
- 멀티스레드는 한 번에 여러 작업을 처리할 수 있지만, 스레드 간의 경쟁으로 인해 자원 공유 및 동기화 문제가 발생할 수 있습니다. 이는 올바르게 처리하지 않으면 예측할 수 없는 결과를 초래할 수 있습니다.
- 반면, 단일 스레드는 하나의 작업을 처리하고 다음 작업으로 이동합니다. 이러한 접근 방식은 자원 공유와 동기화 문제를 방지할 수 있습니다. 또한 단일 스레드의 실행 순서는 예측 가능합니다. 따라서 멀티스레드와 단일 스레드는 각각의 장단점이 있으며, 상황에 따라 선택해야 합니다.
💡 해당 예시에서는 이전에 1개의 스레드만 생성하는 것이 아닌 10개의 스레드를 생성하고 종료하는 것을 확인해 보기 위한 예시입니다.
[예시 조건]
- main() 함수에서 반복문으로 스레드를 10개 생성을 하고 run() 함수를 10번 수행하면서 반복문의 값(1~10)을 전달하였습니다. - run() 함수에서는 전달받은 값을 기반으로 몇 번째 스레드인지 콘솔을 남겼고 또한 Thread.sleep()을 통해서 1초간의 딜레이를 주었습니다.