5. 자주 하는 실수 (Tip)
블로킹 I/O 를 commonPool 에서 실행.
supplyAsync(task)에 executor 를 빼먹으면 코어 수만큼만 동시에 진행되고, 병렬 스트림까지 함께 느려집니다.exceptionally를 체인 중간에 배치. 그 뒤 단계의 예외는 잡히지 않습니다. 복구는 맨 끝, 관찰은whenComplete로 합니다.join()결과만 믿고 예외를 안 봄.thenAccept로 끝나는 체인은 아무도join하지 않으면 예외가 조용히 사라집니다. 반드시 끝에exceptionally나join을 둡니다.타임아웃을 걸고 취소됐다고 생각. 작업은 계속 돕니다. 실제 취소는 HTTP 클라이언트·JDBC 의 타임아웃으로 걸고,
orTimeout은 호출자 보호용으로만 씁니다.thenApply안에서 무거운 작업. future 가 이미 완료돼 있으면 호출 스레드에서 동기로 돕니다. 실행 위치를 통제하려면Async붙은 메서드와 executor 를 씁니다.가상 스레드 안에서
synchronized로 I/O 감싸기. JDK 21 에서는 피닝으로 캐리어가 묶입니다.ReentrantLock으로 바꾸거나 락 밖에서 I/O 합니다.가상 스레드를 풀에 넣기.
newFixedThreadPool에 가상 스레드 팩토리를 주면 장점이 사라집니다. 제한은Semaphore로, 스레드는newVirtualThreadPerTaskExecutor로 씁니다.ThreadLocal에 큰 객체. 가상 스레드 10만 개면 10만 벌이 생깁니다. 요청 범위 값은 작게 유지하고, 캐시 용도로는 쓰지 않습니다.