-
JAVA | 스레드(Thread)programming/JAVA 2020. 5. 30. 00:10
프로세스와 스레드(Thread)
프로세스란?
보통 우리가 만드는 프로그래밍 언어(java,c,c++ 등)로 소스를 짜서 만든 것을 '프로그램' 이라고 한다.
'프로그램'을 실행 시켜 동작하게 만들면 이것을 '프로세스' 라고 한다.
프로세스란 '실행 중인 프로그램' 이다. 즉 프로그램을 실행하면 OS로 부터 실행에 필요한 자원을 할당받아 프로세스가 된다.
프로세스는 프로그램을 수행하는데 필요한 데이터와 메모리 등의 자원 그리고 스레드로 구성되어 있으며
프로세스의 자원을 이용해서 실제로 작업을 수행하는 것이 바로 '스레드' 이다.
* 멀티 태스킹(multi tasking) 은 두 가지 이상의 작업을 동시에 처리하는 것을 말한다.
운영체제는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킨다.
ex) 메신저에서 채팅 기능을 제공하면서 파일 전송 기능을 수행할 수 있는 것
하나의 프로세스가 두 가지 이상의 작업을 처리할 수 있게(멀티 태스킹이 가능하게) 만들어 주는 것이 멀티 스레드이다.
스레드란?
스레드는 한 가닥의 실이라는 뜻인데,
한 가지 작업을 실행하기 위해 순차적으로 실행할 코드를 실처럼 이어 놓았다고 해서 유래된 이름이다.
정리를 하자면 프로세스를 이루는 코드의 실행 흐름 !
하나의 스레드는 하나의 코드 실행 흐름이기 때문에 한 프로세스 내에 스레드가 두 개라면 두 개의 코드 실행 흐름이 생긴다는 의미!
모든 프로세스에는 최소한 하나 이상의 스레드가 존재하며, 둘 이상의 스레드를 가진 프로세스를 멀티 스레드 프로세서 라고 한다.
멀티 프로세스가 애플리케이션 단위의 멀티 태스킹이라면 멀티 스레드는 애플리케이션 내부에서의 멀티 태스킹이라고 볼 수 있다.
멀티 프로세스들은 운영체제에서 할당받은 자신의 메모리를 가지고 실행하기 때문에 서로 독립적이다.
하나의 프로세스에서 오류가 발생하더라도 다른 프로세스에 영향을 미치지 않는다.
하지만 멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를 발생시키면 프로세스 자체가 종료될 수 있어 다른 스레드에게 영향을 미치게 된다.
멀티 스레딩의 장점
- CPU의 사용률을 향상시킨다.
- 지원을 보다 효율적으로 사용할 수 있다.
- 사용자에 대한 응답성이 향상된다.
- 작업이 분리되어 코드가 간결해진다.
* 멀티 태스킹과 마찬가지로 멀티 스레딩은 하나의 프로세스 내에서 여러 스레드가 동시에 작업을 수행하는 것이 가능하다.
실제로는 한 개의 CPU가 한 번에 단 한가지 작업만 수행할 수 있기 때문에 아주 짧은 시간 동안 여러 작업을 번갈아 가며 수행해 동시에 여러 작업이 수행되는 것 처럼 보이게 하는 것이다. 그래서 프로세스의 성능이 스레드의 수에 비례하지 않으며 하나의 스레드를 가진 프로세스보다 두 개의 스레드를 가진 프로세스가 오히려 더 낮은 성능을 보일 수도 있다.
메인 스레드
모든 자바 프로그램은 메인 스레드가 main() 메소드를 실행하면서 시작된다.
메인 스레드는 main() 메소드의 첫 코드부터 순차적으로 실행하고, main() 메소드의 마지막 코드를 실행하거나 return문을 만나면 실행이 종료된다.
멀티 스레드로 실행하는 애플리케이션을 개발하려면 몇 개의 작업을 병렬로 실행할지 결정하고 각 작업별로 스레드를 생성해야 한다. 어떤 자바 애플리케이션이건 메인 스레드는 반드시 존재! 때문에 메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성하면 된다.
스레드 생성 방법
1) java.lang.Thread 클래스로 부터 작업 스레드 객체를 직접 생성
Thread thread = new Thread(Runnable target);
Runnable 은 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라고 해서 붙여진 이름이다.
Runnable 은 인터페이스 타입이기 때문에 구현 객체를 만들어 대입해야 한다.
Runnable에는 run() 메소드 하나가 정의되어 있는데 구현 클래스는 run() 을 재정의해서 작업 스레드가 실행할 코드를 작성해야 한다.
Runnable 구현 클래스 작성하는 법
class Task implements Runnable{ public void run(){ //스레드가 실행할 코드; } }
이렇게 run() 메소드 안에 실행할 코드를 작성해 Runnable 구현 객체를 생성한 후, 이것을 매개값으로 Thread 생성자를 호출하면 비로소 작업 스레드가 생성!
Runnable task = new Task(); Thread thread = new Thread(task);
작업 스레드는 생성되는 즉시 실행되는 것이 아니라, start() 메소드를 호출해야만 실행된다.
thread.start();
[ 스레드를 이용한 비프음 발생 실습 ]
2) Thread 하위 클래스로부터 생성
작업 스레드가 실행할 작업을 Runnable로 만들지 않고, Thread의 하위 클래스로 작업 스레드를 정의하면서 작업 내용을 포함시킬 수도 있다.
Thread 클래스를 상속한 후 run 메소드를 재정의(overriding)해서 스레드가 실행할 코드를 작성하면 된다.
public class WorkerThread extends Thread{ @Override public void run(){ //스레드가 실행할 코드 } }
작업 스레드 클래스로부터 작업 스레드 객체를 생성하는 방법은 일반적인 객체를 생성하는 방법과 동일하다.
Thread thread = new WorkerThread(); //스레드를 실행하고 싶을 경우 위에 객체 생성한 것으로 start() 메소드 호출 thread.start();
* 스레드를 구현하는 방법은 Runnable 인터페이스를 구현하는 방법, Thread 클래스를 상속받는 방법 2가지가 있다.
이 두 가지 방법 중 어느 쪽을 사용해도 별 차이는 없지만 Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없기 때문에, Runnable 인터페이스를 구현하는 방법이 일반적이다.
참고: 이것이 자바다, https://m.blog.naver.com/dydqja2428/220747640002
'programming > JAVA' 카테고리의 다른 글
JAVA | Applet (애플릿) (0) 2020.06.03 JAVA | AWT & Swing (0) 2020.06.02 JAVA | 인터페이스와 추상 클래스 (0) 2020.05.26 JAVA | 추상 클래스 (0) 2020.05.26 JAVA | 인터페이스(Interface) (0) 2020.05.26