해결된 질문
작성
·
469
·
수정됨
0
선생님 안녕하세요. 강의를 듣다가 조금 이상한 부분이 있어서 문의드립니다.
[ 스레드 풀 이해와 구현 ] 강의에서 작성하는 코드를 저도 그대로 따라치면서 실습을 하고 있는데요.
그런데 예시 코드의 동작에 약간의 문제를 발견했습니다.
강의에서 보여주는 코드는 아래와 WorkerThread 코드는 아래와 같습니다.
그런데 제가 한 ThreadPoolMain 클래스에서 Task 를 3000 개 정도 주고, ThreadPoolSize =20 을 주고 돌려보니까, 2가지 이상현상을 확인했습니다.
1. Null Poiniter Exception 발생
중복 처리
각각의 문제가 발생하는 이유를 정리해보니 다음과 같더라구요.
NPE 발생 원인
// 시나리오 1
if (!taskQueue.isEmpty()) {
// 쓰레드 A,B 2개가 동시에 여기에 접근
// 쓰레드 A 가 먼저 Poll 을 해서 가져가버림.
// 쓰레드 B 는 비어있는 Queue 에 대하여 poll, null 을 반환 받음
task = taskQueue.poll();
} else {
continue;
}
// 쓰레드 A 는 정상 시작
// 쓰레드 B 는 NullPointerException!
task.run();
중복처리 원인
// 시나리오 2
if (!taskQueue.isEmpty()) {
// 쓰레드 A,B 2개가 동시에 여기에 접근
// 쓰레드 A 가 먼저 Poll 을 해서 가져 가버림.
// 쓰레드 B 도 Poll 해서 task 를 가져감.
task = taskQueue.poll();
} else {
continue;
}
// 쓰레드 A 는 작업 시작
// 쓰레드 B 도 중복으로 해당 task 실행
task.run();
혹시 코드를 아래처럼 짜야 되는 게 아닌지 조심스럽게 문의해봅니다.
답변 3
1
아 네
그렇군요
질문 내용이 맞습니다
if (!taskQueue.isEmpty()) {
task = taskQueue.poll();
} else {
continue;
}
위 구문도 스레드에 안전하지 않습니다.
일반적으로 taskQueue 같은 경우 BlockingQueue 를 사용하기 때문에 동기화 처리나 중복처리가 기본적으로 구현되어 있기 때문에 동기화 처리를 하지 않았는데 알고보니 BlockingQueue 를 사용하지 않았네요
그렇다면 별도로 동기화 처리를 해 주어야 하기 때문에 synchronized 로 묶어 주어야 합니다.
일단 이번 챕터는 완성된 스레드 풀에 대한 구현을 설명하기 보다는 아주 간단하지만 기본적인 스레드 풀의 흐름을 이해하기 위한 목적으로 이해해 주시면 되겠습니다.
감사합니다.
0
-3
안녕하세요, 인프런 AI 인턴입니다.
식빵님께서 질문하신 스레드 풀의 동작 문제와 관련하여, 강의 중에서 강사님이 context switching에 대해 설명한 내용이 도움이 될 것 같습니다. 이와 관련하여 다른 학습자의 질문에 대한 답변이 이미 제공되어 있으니, 아래 링크를 참고하시어 유사한 문제를 해결하는 데 도움이 되시길 바랍니다.
강의: 자바 동시성 프로그래밍 [리액티브 프로그래밍 Part.1]
제목: [스레드 중지 – flag variable vs interrupt() - 2] 강의 Context Switch 관련 질문있습니다.
답변 링크: Context Switch와 스레드 중지에 대한 강의 질문
이미지 링크:
위 링크에서 스레드의 실행과 중단에 관한 상세한 설명을 찾아보시고, 코드의 문제를 해결하는 데 참고해 보시기 바랍니다.