반응형
대기 중이던 가상 스레드는 누가 다시 깨우고, 어떤 캐리어 스레드에서 다시 실행될까? 핵심은 Poller와 ForkJoinPool이다.Poller는 I/O 준비를 감지해 대기 중인 가상 스레드를 다시 스케줄링 가능하게 만들고,ForkJoinPool 기반 스케줄러는 그 가상 스레드를 어떤 캐리어 스레드에 마운트할지 배정한다.(Poller = I/O 준비 감지, ForkJoinPool = 실행할 가상 스레드 스케줄링) 우선 각각의 역할을 설명하기 앞서 복습할겸 가상 스레드가 네트워크 I/O를 기다리는 상황을 큰 흐름으로 보자.int read = socket.getInputStream().read(buffer);겉으로는 평범한 동기식 코드다.하지만 가상 스레드에서 실행될 때는 내부적으로 다음 흐름으로 동작한다..
Order order = orderRepository.findById(orderId);PaymentResult payment = paymentClient.pay(order);order.complete(payment); 겉으로 보면 DB 조회를 기다리고, 결제 API 응답을 기다리는 코드다.하지만 가상 스레드에서는 대기 중인 동안 OS 스레드를 계속 붙잡지 않을 수 있다. 가상 스레드는 어떻게 블로킹(동기식) 코드처럼 보이면서도 OS 스레드를 계속 붙잡지 않을 수 있을까?결론 부터 말하면, 가상 스레드의 핵심은 블로킹 코드를 없애는 것이 아니다.가상 스레드가 I/O 대기 상태에 들어가면, JVM은 그 가상 스레드를 캐리어 스레드에서 내려놓고 다른 가상 스레드를 실행할 수 있다. 이 흐름을 이해하려면 두 개..
시작하기 앞서 "스레드가 왜 필요한가?"라는 본질적인 질문부터 시작한다. 스레드는 하나의 프로그램 안에서 여러 작업을 독립적인 실행 흐름으로 진행하기 위해 필요하다.예를 들어 서버에 두 사용자(A, B)의 요청이 동시에 들어왔다고 해보자.스레드가 하나뿐이라면 첫 번째 요청이 DB 응답을 기다리는 동안 두 번째 요청은 시작하지 못한다.요청 A 처리→ DB 응답 대기→ 요청 A 완료→ 요청 B 처리 시작 반면 여러 스레드를 사용하면 요청마다 별도의 실행 흐름을 둘 수 있다.스레드 1: 요청 A 처리 → DB 응답 대기스레드 2: 요청 B 처리 계속싱글 코어에서는 여러 스레드가 매우 짧은 간격으로 번갈아 실행되고, 멀티코어에서는 여러 스레드가 실제로 동시에 실행될 수도 있다.즉, 스레드의 핵심 역할은 여러 작..
복합인덱스는 항상 순서가 중요하다고 알려져있다.계층적으로 정렬되는 구조로 (A, B, C) 복합 인덱스가 있을 때 B = 1, C = 1 조건절로 검색하면 A 필드별로 그룹화되 정렬된 B는 전체적으로 정렬되어 있지 않기 때문에 인덱스를 못한다.꼭 인덱스의 컬럼을 모두 사용해야만 인덱스가 사용되는 것은 아니지만, 첫번째 인덱스 조건은 반드시 조회조건에 포함되어야한다.(인덱스 스킵 스캔 조건에 해당하면 말이 다르다)필자는 이 복합 인덱스는 "WHERE 절 순서대로 구성되어야 인덱스를 탄다"라고 이해하고 있었고, 이 개념을 바로 잡고자 한다. 다음과 같은 2개의 복합 인덱스가 있다고 가정하고 시작한다.이 복합 인덱스 중 옵션 A는 별도의 filesort가 발생하고, 옵션 B는 인덱스만으로 조회가 되고 있다. ..