-
Notifications
You must be signed in to change notification settings - Fork 0
Thread
- Multi-tasking
- 여러 작업을 동시에 하는 것
- 동일한 시간에 작동하고, 같은 메모리/자원을 읽고 쓰지만, 다른 일을 한다!
- Java의 멀티태스킹 구현 스탠다드는 Thread를 사용하는 것이다
- Native Threads는 Kernel-Level-Thread로 OS의 지원이 필요하다
- Native Threads는 CPU의 execution threads에 매핑되어 OS가 CPU 코어로 Thread 매핑을 관리한다
-
java.lang.Thread
,java.util.concurrent.Executor
,java.util.concurrent.ExecutorService
- JDK 1.2 버전까지는 User-Level-Thread인 Green Thread가 있었다.
- Solaris 2.6 이전
- User-Level-Thread를 사용함으로써 생기는 문제점
- Java App이 Solaris 환경의 기존 MT 앱들과 상호작용할 수 없음
- Java Threads가 멀티 프로세서에서 병렬적으로 수행될 수 없음
- Java App이 OS concurrency를 활용할 수 없음 (단일, 다중 프로세서 시스템에서)
- 경량 스레드인 가상 스레드를 활용해 OS가 아닌 JVM 내부에서 관리된다
- 일반적인 스레드 모델을 사용하는 것처럼 사용할 수 있지만 가볍고 확장성이 좋음
- 스레드 간 전환 비용 감소 -> 처리량, 확장성 높음
- 스레드 개수 제한 없음
- 프로세스 내에서 동시에 여러 개의 Thread가 실행되는 것
- Thread는 프로세스의 실행 흐름 (Sequence Of Control)
- 단일 스레드 프로세스 : 실행 중 하나의 흐름을 따라 실행
- 멀티 스레드 프로세스 : 여러 개의 흐름을 동시에 실행해 여러 독립적인 작업 수행
- 병렬 처리가 가능해지고, 다중 프로세서가 사용 가능한 경우 동시에 실행되는 작업도 병렬로 처리 가능
- 처리량 향상
- 하나의 프로세스에서 동시 연산 작업을 하고 IO 요청을 처리함
- 응용 프로그램 응답성
- 요청이 개별 스레드로 시작될 수 있어 응용 프로그램이 멈추거나 다른 요청이 완료될 때까지 Block 되지 않음
- 멀티 프로세서 시스템에서 병렬적인 연산과 IO 처리가 가능
- 서버 응답성 향상
- 크거나 복잡한 요청 또는 느린 클라이언트가 다른 서비스 요청을 차단하지 않음
- 서버의 전체 처리량이 훨씬 더 높아짐
- 시스템 리소스 사용 최소화
- 스레드는 시스템 리소스에 미미한 영향을 미침
- 스레드는 프로세스보다 생성, 유지 및 관리에 필요한 오버헤드가 적다
- 프로그램 구조의 단순화
- 스레드는 서버 및 멀티미디어 애플리케이션과 같은 복잡한 애플리케이션의 구조를 단순화하는 데 사용될 수 있습니다. 각 작업에 대해 간단한 루틴을 작성하여 복잡한 프로그램을 설계 및 구현하기 쉽고 사용자 요구의 다양성에 더 적응적일 수 있습니다.
- 향상된 통신
- 스레드 동기화 기능을 사용하여 프로세스 간 향상된 프로세스 간 통신을 제공할 수 있습니다. 또한, 동일한 주소 공간 내에서 실행되는 별도의 실행 스레드들 간에 데이터를 공유하여 매우 높은 대역폭과 지연 시간이 낮은 통신을 제공할 수 있습니다.
- many user thread -> one kernel thread
- App에서 동시 실행할 수 있는 스레드의 수를 마음대로 만들 수 있도록 함
- 모든 스레드 활동이 User Space에서 통제됨
- 하나의 스레드만이 커널로 액세스할 수 있고, 따라서 OS에 의해 스케줄받을 수 있는 엔티티도 하나임
- Solaris system의 Java 스레드 초기 구현.
- one user thread -> one kernel thread
- "true" 멀티 스레딩의 초기 구현
- App에서 만들어진 User-Level-Thread가 커널에게 알려짐
- 모든 스레드는 동시에 커널에 액세스할 수 있음
- 각각의 추가적인 스레드들은 프로세스를 무겁게 하므로 스레드를 사용을 매우 조심스럽고 꼼꼼하게 해야 함
- 당연히, 이 모델이 적용된 Windows NT, OS/2 threads package에서는 지원하는 스레드의 수를 제한한다
- Solarias 시스템의 Java
- 프로그램이 필요한 만큼의 스레드를 가질 수 있음
- User-level-thread 라이브러리를 사용해 커널 스레드 위에서 user level thread를 스케줄링함
- 커널은 활성화된 스레드만 관리함
- Many user level thread -> many kernal level thread
- Two-level-model 이라고도 불린다
- 스레드 개수 제약이 없음 -> 프로그래밍의 어려움을 줄임
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
스레드의 실행 흐름은 두 가지 방법으로 생성할 수 있습니다.
첫 번째 방법은 java.lang.Thread
클래스를 상속받는 것입니다.
상속 받은 하위 클래스는 Thread 클래스의 run 메서드를 오버라이드 해야 합니다.
run 메소드가 오버라이드 되면 하위 클래스의 인스턴스를 할당하고 스레드를 시작할 수 있습니다.
// MyThread.java
class MyThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// minPrime보다 큰 소수 계산
}
}
// Main.java - 스레드를 생성하고 실행
PrimeThread p = new PrimeThread(143);
p.start();
두 번째 방법은 java.lang.Runnable
인터페이스를 구현하는 것입니다.
마찬가지로, Runnable을 구현하는 클래스는 run 메소드를 구현해야 합니다.
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// minPrime보다 큰 소수 계산
. . .
}
}
해당 클래스의 인스턴스를 할당하고, Thread의 생성자에 인수로 전달해 스레드를 시작할 수 있습니다.
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
https://devlog-wjdrbs96.tistory.com/271
public static void yield()
현재 스레드가 프로세스의 사용을 양보하길 원한다는 것을 스케줄러에게 알립니다. (스케줄러는 이를 무시할 수 있습니다.)
CPU를 과다 사용하는 스레드 간 상대적 진행을 개선하기 위한 시도로 사용할 수 있습니다.
실제로 효과를 확인하려면 자세한 프로파일링과 벤치마킹이 필요합니다.
java.util.concurrent.lock
패키지의 동시성 제어 구조를 설계할 때 유용할 수 있습니다.
public static void sleep(long millis)
public static void sleep(long millis, int nanos)
현재 실행 중인 스레드를 지정된 밀리초(나노초 단위까지 가능)동안 잠시 멈추게 합니다.
스레드의 실행이 일지적으로 중지되기 때문에 다른 스레드들에게 CPU 자원을 양보할 수 있습니다.
시간 지연이 필요한 작업을 하는 경우, 스레드 간 조정이 필요한 경우 사용됩니다.
시스템 타이머와 스케줄러의 정밀성에 따라 동작하기 때문에, 이상적인 시간과 약간의 차이가 발생할 수 있습니다.