강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

조원영님의 프로필 이미지
조원영

작성한 질문수

기초 탄탄! 독하게 시작하는 Java Part 3(하) : 소켓과 파일 I/O

파일을 메모리로 추상화 하기

"이전 시간 강의 예제코드 실행시 왜 0bytes가 나오는지"에 대한 설명에 대한 질문 남깁니다!

작성

·

18

0

1:11부터 이전 시간의 예제를 실행했을 때, 왜 0bytes가 나오는지 설명해주시는 부분에 대한 질문입니다!

 

제가 혼자서 생각해봤을 때는 "버퍼 인스턴스에 두 개의 비동기 write 작업이 동시에 접근해서 발생한 스레드 동기화 문제"라고 생각했는데, 강사님께서는 "native 수준에서 비동기 쓰기를 처리하려면 각각의 버퍼가 필요하다"고 설명해주셨습니다.

 

버퍼에 접근해서 데이터를 읽어오면 pos가 읽은 바이트수만큼 증가하고, 그 다음에 버퍼에 접근한 writer는 pos위치부터 읽기 시작하는데 그 뒤로는 데이터가 없기 때문에 읽지 못하게 됩니다.

그런데 매번 0bytes가 나오는건 아니고 어떨 때는 34bytes가 나오기도 했습니다. "버퍼에 접근해서 데이터를 읽어서 pos를 읽은 바이트 수만큼 증가"연산을 하기전에 버퍼에 접근하게 되면 데이터를 읽어올 수 있게 되는 것 같다고 생각했습니다.

buffer.get(data.getBytes()); 

위 코드를 asyncChannel.write 하기 전에 실행해본결과 모두 0bytes가 나오는 걸 보고, 버퍼의 상태에 따라서 결과가 달라진다고 판단했습니다.

따라서, 버퍼에 두 스레드가 동시 접근하면서 발생하는 동기화 문제다 라고 생각했습니다!

 

제가 이해한 것이 틀린것인지 강사님과의 답변과 어떤 차이가 나는건지 궁금해서 질문남깁니다!

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 조원영님,

강사님이 설명하신 “native 수준에서 비동기 쓰기를 처리하려면 각각의 버퍼가 필요하다”라는 것은 비동기 I/O 작업을 수행할 때, 각 작업이 별도의 버퍼를 사용해야 데이터의 무결성을 보장할 수 있다는 의미입니다.

조원영님께서 언급하신 것처럼 두 개의 비동기 write 작업이 같은 버퍼에 동시에 접근할 경우, 스레드 동기화 문제로 인해 예상치 못한 결과가 발생할 수 있습니다. 특히, pos 값이 정확히 관리되지 않으면 데이터가 읽히지 않거나, 덮어씌워질 위험이 있습니다.

매번 0bytes가 나오지 않고 34bytes가 나올 때도 있는 이유는 경쟁 상태(race condition) 때문일 수 있습니다. 즉, 두 쓰레드가 버퍼를 비정상적인 순서로 접근하면서 생기는 문제입니다. buffer.get(data.getBytes());를 실행함으로써 버퍼의 상태가 변하게 되고, 이로 인해 다음 write 작업에 영향을 미치는 것입니다.

결론적으로, 조원영님이 말씀하신 스레드 동기화 문제와 강사님이 말씀하신 각각의 버퍼 사용 필요성은 같은 문제의 다른 측면을 설명하고 있는 것으로 볼 수 있습니다. 각 비동기 작업이 별도의 버퍼를 사용하도록 설정하면, 이러한 데이터 손실 문제를 방지할 수 있습니다.

좀 더 자세한 예제와 설명은 Spring Boot Reference Documentation를 참고하실 수 있습니다.

감사합니다!

조원영님의 프로필 이미지
조원영

작성한 질문수

질문하기