Multithreading, blocking I/O, and asynchronous I/O are discussed. Blocking I/O causes CPUs to be idle waiting for I/O to complete. Multithreading and asynchronous non-blocking I/O allow the CPU to switch between threads/processes while waiting for I/O, improving CPU utilization. Asynchronous I/O removes the need for threads by notifying the CPU when I/O is complete, but multiple threads may still be useful when multiple CPUs are present to improve parallelism. Examples show how asynchronous I/O has enabled high concurrency web servers with tens of thousands of simultaneous connections.