DEV
-
Java 스레드에서 InterruptedException을 어떻게 처리해야 할까?
멀티스레드 환경에서 InterruptedException은 다른 예외들과는 성격이 완전히 다르다.단순히 “오류가 발생했다”라는 의미가 아니라, 스레드를 종료하라는 의도적인 신호다.이 신호를 어떻게 다루느냐에 따라 시스템이 정상적으로 종료될 수도 있고,반대로 종료되지 않는 스레드가 남아 장애로 이어질 수도 있다.아래는 InterruptedException을 올바르게 처리하는 방법과잘못 처리했을 때 생기는 문제들을 정리한 내용이다.InterruptedException은 “스레드를 멈춰라”라는 신호다다른 일반적인 예외(IOException, RuntimeException, etc.)는오류 상황을 나타낼 뿐이다.하지만 InterruptedException은 외부에서 스레드에 보낸 종료 요청이다.이 신호가 발생하..
2025.12.09 13:29 -
volatile vs atomic — 헷갈리는 두 개념 완벽 정리
멀티스레드 프로그래밍을 하다 보면 volatile과 atomic의 차이에서 한 번쯤 혼란을 겪게 된다.둘 다 동시성과 관련된 키워드지만, 그 역할은 분명히 다르다.이 글에서는 두 개념을 CPU 동작부터 코드 레벨까지 명확하게 정리해본다. 1. volatile — “항상 최신 값을 보게 하라” volatile은 가시성(visibility) 을 보장하기 위한 키워드다.일반 변수는 CPU 캐시에 저장되어, 다른 스레드가 변경한 값을 즉시 반영하지 못할 수 있다.하지만 volatile을 붙이면 해당 변수를 항상 메인 메모리에서 직접 읽고 쓰도록 강제한다.어떤 블로그를 보니 [그 변수를 휘발성 메모리에 만들어라] 라고도 표현해두었네. volatile int count;이렇게 선언하면 모든 스레드가 항상 count..
2025.10.09 18:05 -
AtomicBoolean
AtomicBoolean 이란?AtomicBoolean은 Java에서 제공하는 원자적(atomic) 인 불리언(Boolean) 변수예요.AtomicBoolean isRunning = new AtomicBoolean(false); 이 한 줄로 만든 변수는true / false 값을 저장한다는 점에서는 일반 boolean과 같지만,멀티스레드 환경에서도 동기화 문제 없이 안전하게 읽기/쓰기가 가능합니다.즉, 여러 스레드가 동시에 isRunning을 읽고/바꾸더라도 race condition이 발생하지 않음. compareAndSet() 메서드란?compareAndSet(expectedValue, newValue)는 “현재 값이 expectedValue면, 그때만 newValue로 바꿔라” 라는 의미입니다.이게..
2025.10.09 17:46 -
jstat로 JVM 메모리 모니터링: 실무용 해석 가이드
스프링 부트 같은 자바 애플리케이션을 운영하다 보면 “왜 느려졌지?”라는 순간이 반드시 온다.이때 가장 먼저 확인할 수 있는 저비용 도구가 바로 jstat이다.이 글은 jstat을 바로 써먹을 수 있는 수준으로 정리했다. 설치 방법 설명 대신, “어떤 옵션으로 찍고, 각 헤더가 무엇을 의미하며, 무엇을 보면 이상 신호인지”에 집중한다.1. jstat 한 줄 요약무중단으로 JVM 내부 메모리 지표를 뽑는 도구GC(Young/Old), Metaspace, 클래스 로딩, 컴파일러 상태 등을 주기적으로 관찰 가능jstat - [간격ms] [횟수]예)jstat -gcutil 1000→ 1초마다 힙/메타스페이스 사용률과 GC 횟수/시간을 요약해 보여준다.2. 가장 많이 쓰는 옵션 3종2.1 -gcutil : 사..
2025.08.12 16:43 -
스프링 부트 GC 로그 해석 실전 — Metadata GC Threshold로 Full GC가 길어질 때
운영 중 서비스가 갑자기 멈춘 듯 느려지고, 모니터링에 긴 스파이크가 찍히는 순간이 있다. 이럴 때 GC 로그는 원인을 추정이 아닌 증거로 보여준다. 특히 다음과 같은 문구가 보인다면 메타스페이스(Metaspace)가 범인일 가능성이 높다.Pause Full (Metadata GC Threshold) 214M->214M(2048M) 43012.7ms이번 글은 이 한 줄을 어디까지 읽어낼 수 있는지, 그리고 실제로 무엇을 확인하고 어떻게 조치하는지 단계별로 정리한다.1) 샘플 로그와 한 줄 해석다음은 실제 운영에서 캡처한 패턴을 단순화한 예시다. (Java 11, G1GC, unified logging)[2.431s][info][gc] GC(365) Pause Young (Concurrent Start) ..
2025.08.12 15:08 -
DMA를 알면 고성능 소켓이 보인다. 네트워크 I/O의 세계로 들어가기
널널한 개발자님의 인프런 강의를 정리한 글입니다.글을 읽기 전에 알면 좋은 배경 지식1. 운영체제의 역할컴퓨터의 하드웨어는 우리가 직접 접근할 수 없습니다. 대신 운영체제(OS)가 하드웨어를 제어해줍니다. 예를 들어 파일을 저장하거나, 인터넷을 통해 데이터를 보내는 등의 작업은 모두 운영체제를 통해 간접적으로 수행됩니다.운영체제는 다음과 같은 층위 구조로 되어 있습니다.[ Application ] ← 우리가 직접 사용하는 프로그램[ Kernel ] ← 하드웨어 제어 및 자원 관리[ Hardware ] ← 물리 장치 (CPU, Memory, NIC 등) 2. 소켓(Socket)이란?네트워크 통신을 위해 사용하는 프로그래밍 인터페이스입니다. 예를 들어, 웹 브라우저가 서버에 요청을 ..
2025.07.14 23:20 -
Mono 고급 정리 - zip, fromCallable, block까지 실전 활용 정리
이전 글에서 Mono의 기본 생성 방식과 연산자들 (flatMap, map, switchIfEmpty 등)을 정리했었다.이번에는 한 단계 더 나아가서, 실무에서 자주 마주치는 상황에서 어떻게 Mono를 응용할 수 있을지 다뤄보자. 1. Mono.zip() - 여러 Mono를 병렬로 실행하고 결과를 합칠 때zip()은 두 개 이상의 Mono를 동시에 실행해서, 결과를 묶어서 처리할 수 있게 해준다.(모든 Mono가 완료되기 전까지는 실행되지 않음)예제: 사용자 정보와 포인트 정보를 동시에 가져오기Mono userMono = userRepository.findById("123");Mono pointMono = pointService.getPointByUserId("123");Mono> zipped = Mon..
2025.05.20 22:21 -
Spring WebFlux의 Mono
Spring WebFlux를 처음 시작하면 가장 먼저 마주치는 게 바로 Mono와 Flux다.이 중 Mono는 "0 또는 1개의 데이터를 비동기적으로 처리하는 Publisher"다.한 줄 요약: Mono는 '1개의 데이터 또는 아무 것도 없는' 비동기 데이터 그릇이다. 왜 Mono를 써야 할까?전통적인 Spring MVC에서는 메서드가 값을 리턴하면, 그 값은 동기적으로 바로 반환된다.하지만 WebFlux는 Reactive Streams 기반으로 동작하기 때문에, Mono를 통해 데이터를 "나중에", "비동기로", "필요할 때" 처리한다.@GetMapping("/user/{id}")public Mono getUser(@PathVariable String id) { return userReposito..
2025.05.20 22:15