servlet 3.0은 async 지원됐지만 blocking io였음 -> servlet thread가 작업을 worker thread로 미뤄서 throughput은 늘었지만, blocking io라서 worker thread를 io가 계속 점유함 -> 리소스 차원에서는 오히려 thread를 더 많이 생성하게 됨 (servlet thread외에 worker thread도 생성하니까)
servlet 3.1은 nonblocking io 지원 -> WriteListener.onWritePossible()에서 isReady()가 true이면 iterative하게 게속 스트림 사용 가능 -> recursion이 아니라 스택오버플로우 안생김 -> isReady()가 false이면 return하고, onWritePossible()을 스케쥴링함 -> 추후에 onWritePossible이 실행됨. 이때 실행은 새로운 쓰레드에서 됨. 새로운 쓰레드이므로 마찬가지로 스택오버플로우 방지 -> onWritePossible()은 servlet thread가 아닌 새로운 쓰레드에서 실행되지만 non blocking io이기 때문에 io가 준비되어있지 않으면 바로 return하고 servlet container가 onWritePossible()을 호출해줄 때까지 기다린다. 그래서 servlet 3.0과는 달리 thread가 자원을 오래 점유하지 않게 된다.