해결된 질문
작성
·
93
·
수정됨
0
[비교 결론]
(맥북 프로 2018형 기준)
yield() 사용 X: 체크 로직 319_216_379
회 수행
yield() 사용 O: 체크 로직 000_730_447
회 수행
[코드 사용법]
체크로직 while loop에 있는 Thread.yield();
를 주석처리 on/off 하면서 체크하시면 됩니다.
프로그램 수행 -> a, b, c, d, e, q를 순서대로 입력
위 두 동작을 주석처리 on/off한 후에 실행하는 두 경우 모두에서 비슷한 속도로 해 주시면 비교가 더 명확합니다.
[코드 설명]
MyPrinterV4 코드를 기준으로 하여 다음과 같이 체크 로직의 수행 횟수를 카운트할 수 있도록 개선했습니다. 러프하게 작성한 코드라서 세부적인 부분은 무시바랍니다.
// 체크 로직의 수행 횟수를 기록하는 변수
private static int count = 0;
while (!Thread.interrupted()) {
if (jobQueue.isEmpty()) {
count++; // 체크 로직 수행시 1회 추가 기록
Thread.yield(); // 여기를 On/Off하며 체크
continue;
}
}
// 메인 함수의 마지막 부분에 추가한 코드
// q를 입력하여 프로그램을 종료했을 때까지 수행된 체크 로직의 횟수를 출력
System.out.println(count);
[전체 코드]
package thread.control.printer;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.ConcurrentLinkedQueue;
import static util.MyLogger.log;
public class MyPrinterV4 {
// 추가된 코드
private static int count = 0;
public static void main(String[] args) {
Printer printer = new Printer();
Thread printerThread = new Thread(printer, "printer");
printerThread.start();
Scanner userInput = new Scanner(System.in);
while (true) {
log("프린터할 문서를 입력하세요. 종료 (q): ");
String input = userInput.nextLine();
if (input.equals("q")) {
printerThread.interrupt();
break;
}
printer.addJob(input);
}
// 추가된 코드
System.out.println(count);
}
static class Printer implements Runnable {
Queue<String> jobQueue = new ConcurrentLinkedQueue<>();
@Override
public void run() {
while (!Thread.interrupted()) {
if (jobQueue.isEmpty()) {
// 코드 추가된 부분(시작)
count++;
Thread.yield(); // 주석 on/off 하며 비교
// 코드 추가된 부분(종료)
continue;
}
try {
String job = jobQueue.poll();
log("출력 시작: " + job + ", 대기 문서: " + jobQueue);
Thread.sleep(3000);
log("출력 완료: " + job);
} catch (InterruptedException e) {
log("인터럽트 발생. message=" + e.getMessage());
break;
}
}
log("프린터 종료");
}
public void addJob(String input) {
jobQueue.offer(input);
}
}
}
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
dev.rudevico님께서 공유해주신 yield()
여부에 따른 체크 로직의 수행 횟수를 확인할 수 있는 코드에 대한 실험은 자바의 Thread.yield()
메서드가 실제로 시스템 스케줄링에 얼마나 영향을 미치는지 보여주는 좋은 예시입니다.
Thread.yield()
는 현재 스레드가 실행 중인 작업에서 물러나 다른 가능한 스레드에게 CPU를 양보하는 역할을 합니다. 일반적으로 이 메서드는 스레드 우선순위가 동일한 다른 스레드에게 자원을 제공하려고 할 때 사용됩니다. 따라서 yield()
를 사용할 경우, 다른 스레드가 더 빠르게 교체되어 실행될 수 있어 체크 로직의 수행 횟수가 줄어들 수 있습니다.
하지만, yield()
의 실제 동작은 JVM 구현 및 운영 체제에 밀접하게 의존하므로, 반드시 실행 횟수나 실행 시점에 큰 차이를 주지 않을 수도 있습니다. 이는 주로 프로세스 스케줄러의 구현 및 시스템의 부하 상태에 따라서 달라질 수 있습니다.
관련하여 비슷한 내용이 논의된 인터럽트 - Thread의 사용 게시물을 참고하시면 추가적인 이해에 도움이 될 수 있습니다.
또한, Thread.interrupt()
를 사용하는 방법과 관련된 질문과 답변은 인터럽트에 대해 질문 있습니다 게시물에서 확인하실 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.