프로세스 내에서 실행되는 흐름의 단위.
하나의 프로세스 내에서 2개이상의 스레드가 동시에 작업을 수행하는것.
자바에서 스레드를 생성하는 방법
run( )
메서드를 정의run( )
메서드를 정의class SubThread implements Runnable {
// 자바의 서브스레드
@Override
public void run() {
for(int i=1; i<6; i++) {
try {
System.out.println("서브스레드 : " + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadEx01 {
// 자바의 메인스레드
public static void main(String[] args) {
SubThread st = new SubThread();
Thread t1 = new Thread(st); // 타겟 선정
t1.start(); // run() 메서드 실행
for(int i=1; i<6; i++) {
try {
System.out.println("메인스레드 : " + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
코드 실행 순서
자바를 처음 실행하면 메인스레드 1개만 가지고있는 main( ) 메서드가 실행된다.
SubThread 클래스의 객체(st)를 생성한다.
Thread 객체(t1)를 생성하고 그 안에 타겟(st)을 선정하면 run( ) 메서드가 호출되고 run 스레드가 생성된다.
이때 start( ) 메서드를 호출했는데 왜 run( ) 메소드가 호출된것일까?
--> start( ) 메서드 내부에 start0( ) 메서드가 있고
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
start0( ) 메서드 내부에는 run( ) 메서드를 호출하도록 구현되어 있다.
private native void start0();
/**
* If this thread was constructed using a separate
* {@code Runnable} run object, then that
* {@code Runnable} object's {@code run} method is called;
* otherwise, this method does nothing and returns.
* <p>
* Subclasses of {@code Thread} should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
run( ) 메서드 내의 for문이 시작되면 끝날때까지 기다리지않고 문맥교환(Context switching)을 통해서 main( ) 메서드 내의 for문도 실행시킨다.
따라서 결과를 보면 서브 스레드, 메인 스레드가 동시에 실행 되는것을 확인 할 수있다.
자바 어플리케이션은 프로세스가 존재하지않고 메인스레드 밖에 없기 때문에 필요에 따라 작업스레드를 만들어서 메인스레드와 작업스레드를 동시에 병렬로 실행시킬수도 있다.
일의 순서가 있다. (메인 스레드인 CPU가 다른 메인스레드에게 일을 시키고 그 일이 끝날때까지 CPU는 대기 상태에 있다)
일의 순서가 없다. (메인 스레드인 CPU가 다른 스레드에게 일을 시키고 메인 스레드인 CPU는 계속해서 일을 한다)
작업요청이 여러개 들어왔을때 1개의 스레드가 요청이 들어온 순서대로 1개의 요청에 대한 결과를 처리하고 나서 그 다음 요청을 처리하는것.
ex) 우체국 1개가 여러 손님을 처리. 손님1이 우체국 일을 볼때 손님 2,3,4,...... 는 손님1의 일이 끝날때까지 기다려야한다.
작업요청이 들어온만큼 스레드를 만들어서 처리.
스레드가 작업요청만큼 생기므로 성능 저하 발생.
ex) 우체국을 손님수만큼 만든다. 손님1은 우체국1에서, 손님2는 우체국2에서, ..... 우체국이 너무 많아서 성능 저하 발생.
작업요청이 여러개 들어왔을때 1개의 스레드가 요청이 들어온 순서에 상관없이 요청을 처리하는것
ex) 우체국은 1개이지만 손님1~손님100까지 집에서 기다린다. 우체국은 우편이 도착하면 손님에게 알려주고 그때와서 손님이 우체국에 와서 일을 처리.
작업요청이 여러개 들어왔을때 몇개정도의 스레드를 만들어서 비동기로 처리하는것.
ex) 싱글스레드 - 비동기 방식의 우체국을 대략 몇개정도만 만든다음 각 우체국들이 비동기 방식으로 처리하는것.
출처
- 이지업 컨텐츠 내의 데어프로그래밍 자바강의
- https://math-coding.tistory.com/171